如何模拟一个值以使用 JUnit/Mockito 在另一个方法中测试条件?
How to mock a value to test a conditional in another method with JUnit/Mockito?
我是 JUnit 和 Mockito 的新手,正在努力模拟从布尔方法返回的值以命中条件。
我试过 this post 的答案,但似乎对这个不起作用。我试过使用间谍,thenCallRealMethod,无法弄清楚。
我已经测试了该值何时为真,但我似乎无法进入 else 部分进行测试。
这是我所做的一个例子:
ServiceImpl.java 有一个调用布尔方法 shouldRegister() 的方法 register()。 shouldRegister() 方法只是检查另一个服务以查看布尔值是真还是假,然后 returns 那个。
如果为 true,它会构建一个 JsonNode 负载来发送,否则,如果为 false,它会从负载中删除一个字段。
// ServiceImpl.java:
// in the record() method:
if (body.has("fieldtoBeRemoved")) {
if (shouldRegister()) {
((ObjectNode) body).set("fieldtoBeRemoved");
} else {
// this is the line I am trying to test
((ObjectNode) body).remove("fieldtoBeRemoved");
}
}
// method being called above in the conditional
protected boolean shouldRegister() {
Optional<String> flag = configService.getString("booleanValue");
String stringFlag = flag.orElse("false");
return BooleanUtils.toBoolean(stringFlag);
}
// In the test
@InjectMocks
private ServiceImpl serviceImpl;
@Test
public void testingForFalse() {
serviceImpl = new ServiceImpl();
// what I am struggling with, trying to make the value false,
// so that it hits the else in the record() method in ServiceImpl
// and removes fieldtoBeRemoved from the payload
when(serviceImpl.shouldRegister()).thenCallRealMethod();
doReturn(false).when(spy(serviceImpl)).shouldRegister();
assertThat(fieldtoBeRemoved, is(""));
}
当我 运行 这样做时,它失败了,因为 fieldtoBeRemoved 的值不为空,它具有负载中字段的值,它不应该有。我猜这个值仍然返回 true,因为我没有嘲笑它 correctly/setting 对于这个测试用例它是 false。我也试过模拟对 record() 方法的调用。
任何帮助表示赞赏!
如果源代码和测试在同一个包中并且 shouldRegister
至少 package-private
,您可以这样做
@Test
public void testingForFalse() {
serviceImpl = new ServiceImpl() {
@Override
public boolean shouldRegister() {
return false;
}
}
// rest of the test
}
在这种情况下,您不需要对此方法进行任何模拟。
我是 JUnit 和 Mockito 的新手,正在努力模拟从布尔方法返回的值以命中条件。
我试过 this post 的答案,但似乎对这个不起作用。我试过使用间谍,thenCallRealMethod,无法弄清楚。
我已经测试了该值何时为真,但我似乎无法进入 else 部分进行测试。
这是我所做的一个例子:
ServiceImpl.java 有一个调用布尔方法 shouldRegister() 的方法 register()。 shouldRegister() 方法只是检查另一个服务以查看布尔值是真还是假,然后 returns 那个。
如果为 true,它会构建一个 JsonNode 负载来发送,否则,如果为 false,它会从负载中删除一个字段。
// ServiceImpl.java:
// in the record() method:
if (body.has("fieldtoBeRemoved")) {
if (shouldRegister()) {
((ObjectNode) body).set("fieldtoBeRemoved");
} else {
// this is the line I am trying to test
((ObjectNode) body).remove("fieldtoBeRemoved");
}
}
// method being called above in the conditional
protected boolean shouldRegister() {
Optional<String> flag = configService.getString("booleanValue");
String stringFlag = flag.orElse("false");
return BooleanUtils.toBoolean(stringFlag);
}
// In the test
@InjectMocks
private ServiceImpl serviceImpl;
@Test
public void testingForFalse() {
serviceImpl = new ServiceImpl();
// what I am struggling with, trying to make the value false,
// so that it hits the else in the record() method in ServiceImpl
// and removes fieldtoBeRemoved from the payload
when(serviceImpl.shouldRegister()).thenCallRealMethod();
doReturn(false).when(spy(serviceImpl)).shouldRegister();
assertThat(fieldtoBeRemoved, is(""));
}
当我 运行 这样做时,它失败了,因为 fieldtoBeRemoved 的值不为空,它具有负载中字段的值,它不应该有。我猜这个值仍然返回 true,因为我没有嘲笑它 correctly/setting 对于这个测试用例它是 false。我也试过模拟对 record() 方法的调用。 任何帮助表示赞赏!
如果源代码和测试在同一个包中并且 shouldRegister
至少 package-private
@Test
public void testingForFalse() {
serviceImpl = new ServiceImpl() {
@Override
public boolean shouldRegister() {
return false;
}
}
// rest of the test
}
在这种情况下,您不需要对此方法进行任何模拟。