java单元测试模拟输入_java – 如何对此进行单元测试(使用模拟或经典单元测试?)...

我需要为以下方法编写一个JUnit测试(简化):

/** Return name of previous entry or name of given entry if no previous entry. */

public String getPreviousName(TreeEntry entry) {

if (entry.getPrevious() != null) {

return entry.getPrevious().getName();

} else {

return entry.getName();

}

}

我只是不知道应该怎么测试这个.我也可以

a)使用Mocks模拟参数及其先前的条目或

b)创建一个真正的TreeEntry,它是真正的前一个条目

使用模拟的问题是,我需要在测试用例中说明实际实现需要使用哪种方法,例如:在这里我说正确的名称是通过TreeEntry的getPrevious()然后通过前一个条目的getName()获得的(不考虑if null情况,因为这基本上不是问题):

TreeEntry mockEntry = mock(TreeEntry.class);

TreeEntry mockPreviousEntry = mock(TreeEntry.class);

when(mockEntry.getPrevious()).thenReturn(mockPreviousEntry);

when(mockPreviousEntry.getName()).thenReturn("testName");

assertEquals("testName", classUnderTest.getPreviousName(mockEntry));

但是实现者也可以像这样实现它:

return NameService.getName(entry.getPrevious());

这对测试无关紧要.

但是,如果我使用经典单元测试而没有模拟,我还有另一个问题. TreeEntry的构造函数非常复杂.它有5个参数需要有效的对象.所以创建类似的东西非常复杂:

TreeEntry entry = new TreeEntry(...);

TreeEntry previousEntry = new TreeEntry(...);

entry.setPrevious(previousEntry);

previousEntry.setName("testName");

assertEquals("testName", classUnderTest.getPreviousName(entry));

代码会比这长得多,因为构造函数需要复杂的参数.另一件事是构造函数访问文件系统以从那里加载它的内容,因此它增加了使单元测试更慢.

使用经典方法,它还将测试与TreeEntry的实现联系起来.因为如果在TreeEntry中使用构造函数或前一个条目的设置更改了某些内容,则还需要在测试中更改它.如果它被遗忘,它将导致测试失败,即使是严格的测试类也不是TreeEntry.

你会说什么是单元测试的正确方法?

我个人倾向于更喜欢嘲弄的方法.是否可以说在测试用例中我已经指定了哪个是被测试类的合作者,因为这在某种程度上也更多地属于设计而不是实现?

最好的祝福,

亚历克斯

最佳答案 我认为你的模拟方法看起来很好(我同意如果TreeEntry像你说的那样复杂,你不应该将它们混合到这些测试中(但我希望你在其他地方测试TreeEntry)).如果您正在编写这样的大量测试,那么您应该考虑使用一些Builder模式(如果您有耐心的话,可以使用流利的语法),以便您可以构建模拟,例如像这样:

BuildANew.TreeEntry().WithPreviousEntryName("testName");

或者您可以创建一个ITreeEntry接口并根据该接口编写树操作代码,并创建一个简单的存根实现以传递到您的测试中,这样您就不需要乱用模拟设置代码.或者,为了更清晰的方法,创建界面并模拟它.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值