Class A
{
public B makeB(int q)
{
return new B(q);
}
public boolean evaluate(int q)
{
B b = makeB(q);
boolean result = b.get();
return result;
}
}
Class B
{
int e;
public B(int w)
{
e=w;
}
public boolean get()
{
//return boolean based on object B
}
}
Class ATest
{
A a = spy(A.class);
B b1 = mock(B.class);
B b2 = mock(B.class);
doReturn(b1).when(a).makeB(5);
doReturn(b2).when(a).makeB(10);
when(b1.get()).thenReturn(true);
when(b2.get()).thenReturn(false);
a.evaluate();
}
======================
在这里,我想从方法中返回true,当对象b包含值5时,如果它包含值10。
。B类来自外部图书馆。
新的单位测试和摩擦图。
其他答案在技术上是正确的,但是 first 要理解的东西:您应该努力使用不是使用这样的模仿框架。
请记住:模拟框架的目的仅是,以使测试成为可能/更容易。您的模拟规格应该尽可能简单。含义:与其考虑对不同参数的模拟给出不同的结果 - 更好的解决方案是具有不同的测试和模拟规格,例如:
@Test
public void testFooWithA() {
when(someMock.foo(eq(whateverA)).thenReturn(bar);
...
@Test
public void testFooWithB() {
when(someMock.foo(eq(whateverB)).thenReturn(somethingElse);
...
在某些情况下,您编写了更复杂的代码,以使您的模拟"更聪明"。但是大多数时候,当我必须这样做时 - 我逐步支持,简化了我的设计。换句话说:当您的测试变成"太复杂"时 - 最常见的是太复杂类/方法正在测试。
您可以使用Mockito的Answer
接口来实现它。它使您可以访问Call的实际参数,并且您可以根据此区分返回的值。
给定接口
interface Measurer {
int measureLength(String s);
}
一个示例用法看起来像
Measurer measurer = Mockito.mock(Measurer.class);
Mockito.when(measurer.measureLength(Mockito.any(String.class)))
.then((Answer<Integer>) invocationOnMock -> {
String arg = invocationOnMock.getArgumentAt(0, String.class);
if (arg.length() < 10) {
// mock Measurer can measure only short strings
return arg.length();
}
else {
return 42;
}
});
System.out.println(measurer.measureLength("abc")); // 3
System.out.println(measurer.measureLength("abcdefghijklmn")); // 42
在这种情况下,您可以做:
doAnswer(new Answer<Boolean>() {
public Boolean answer(InvocationOnMock invocation) {
return invocation.getArgument(0) == 5;
}}).when(a.evaluate());
如果您要问如何在#evaliate()实际实现中获得" b"的实际值返回的,所以您知道它最后一次返回了什么,然后您可以根据该本地变量的值获得回答()返回。
是:
B lastB = null;
Answer<B> lastBAnswer = new Answer<B>() {
public B answer(InvocationOnMock invocation) {
if (invocation.<Integer>getArgument(0) == 5) {
lastB = b1;
} else {
lastB = b2;
}
return lastB;
}
};
doAnswer(lastBAnswer).when(a).makeB(any());
doAnswer(new Answer<Boolean>() {
public Boolean answer(InvocationOnMock invocation) {
return lastB.get();
}
}).when(a).evaluate();
我不建议那条路,因为它依赖于时间凝聚力,但是对于测试可以接受。
注意:通过stackoverflow回答而不语法检查此问题。可能会有些偏离,但这是一个粗略的想法。