【发布时间】:2017-04-26 16:56:44
【问题描述】:
首先:我为我的问题找到了一些解决方案,但“最新”的解决方案是从 2014 年开始并使用反射,所以我希望我可以为我的问题找到一些更高级的解决方案。
情况就是这样,关于migrateUser 和canAdd。这是一个示例类,可以让我的问题很容易看到。
public class UserInterfaceImpl implements UserInterface {
private final List<T> accountList = new LinkedList<>();
private final AccountInterface accountInterface;
private boolean bonusReceived = false;
public UserInterfaceImpl(AccountInterface accountInterface) {
this.accountInterface = accountInterface;
}
public void migrateUser(AccountMergerInterface accountMerger, UserInterface oldUser) {
boolean success = accountMerger.performChange(this, oldUser);
if (success && !bonusReceived) {
//addBonus
accountInterface.deposit(1);
bonusReceived = false;
}
}
public boolean canAdd() {
return accountList > 0;
}
public AccountInterface getAccount() {
return accountInterface;
}
}
migrateUser 方法更改了一些与我的测试无关的帐户数据,因为我当然会单独测试它(应该像我目前所读的那样)。
所以我想知道,如何查看该类的行为是否正确更改了bonusReceived?不使用反射并尽可能复杂?
我的第一次尝试是:
@Test
public void testMigrateUser() {
AccountMergerInterface test = mock(AccountMergerInterface.class);
// define return value for method getUniqueId()
when(test.performChange()).thenReturn(true);
}
但现在我无法继续。在我的示例中,规则应该是没有 getter 和 setter!这个类应该像我的例子。
我不知道该怎么做:
- 将
bonusReceived设置为假之前migrateUser被执行,accountInterface.deposit(1);被不执行 - 如果
if()continue 为 true,则查看bonusReceived是否会设置为 false。 - List 的相同问题:如何访问 List 的私有字段,添加一个 Object 以便返回值为 true 或 false。或者我应该“模拟”一个列表,如果是,我该怎么做?
提前致谢!
【问题讨论】:
-
重构代码是一种选择吗?
-
一种选择是对类的外部可见行为进行单元测试。这带来的好处是,即使私有实现发生变化,您的单元测试仍然有效,这是单元测试的要点之一。如果你真的想测试私有实现的各个方面,一种方法是提供包保护成员,并将单元测试放在同一个包中。
-
Timothoys 的回答很到位。您不希望您的单元测试知道这个私有布尔值。您只想测试给定的“此”输入“结果显示。如何实现不应该是您的测试的一部分。或者您是否打算在每次重构生产代码时更改您的测试?!
标签: java testing junit mocking