对于JUnit测试,我想模拟一个重载方法。但是,无需在mockbuilder中实现多个方法。 我想做这样的事情:
Mockito.when(mock.getSomeInfo(Mockito.any(ArgumentType1.class) OR Mockito.any(ArgumentType2.class), Mockito.any(ArgumentType3.class))).then(new Answer<AnswerType>() {..}
我知道它不适用于OR
声明,但在Mockito中还有另一种方法吗?
答案 0 :(得分:1)
您可以使用自定义matcher执行此操作。
警告:使用复杂的参数匹配是合理的,尤其是自定义参数匹配器,因为它会降低测试的可读性。有时最好为传递给模拟的参数实现equals()(Mockito自然地使用equals()进行参数匹配)。这可以使测试更清洁。
public class TypeOrMatcher extends ArgumentMatcher<Object> {
private final List<Class<?>> clazzes;
public TypeOrMatcher(Class<?>...clazzes) {
this.clazzes = new ArrayList<Class<?>>(clazzes);
}
public boolean matches(Object actual) {
if (actual == null) {
return false;
}
Class<?> actualClass = actual.getClass();
for (Class<?> clazz : clazzes) {
if (clazz.isAssignableFrom(actualClass) {
return true;
}
}
return false;
}
}
TypeOrMatcher isTypeOneOrTwo = new TypeOrMatcher(
ArgumentType1.class, ArgumentType2.class);
Some mockObj = mock(Some.class);
when(mockObj.someMethod(argThat(isTypeOneOrTwo), any(ArgumentType3.class))
.thenReturn(true);
答案 1 :(得分:1)
您可以预先创建要返回的答案对象,然后返回此答案。
class A {
public int test(final String s) {
return 0;
}
public int test(final int i) {
return 0;
}
}
在测试方法中:
public void testAtest() {
final A a = Mockito.mock(A.class);
final Answer<Integer> answer = new Answer<Integer>() {
@Override
public Integer answer(final InvocationOnMock invocation) throws Throwable {
return 0;
}
};
Mockito.when(a.test(Matchers.anyInt())).then(answer);
Mockito.when(a.test(Matchers.anyString())).then(answer);
}
答案 2 :(得分:0)
举个例子,我有一个将从测试方法中调用的服务类:
public interface AService{
public ReturnObject addNewItem(String param1, String param2);
public ReturnObject addNewItem(String param1, String param2, boolean isOk);
}
在MainServiceImpl类中有一个方法将调用如下的重载方法:
@Service("mainService")
public class MainServiceImpl implements MainService {
@Autowired
private AService aService;
public ReturnObject saveItem(String itemName, String itemCode){
return aService.addNewItem(itemName, itemCode);
}
}
因此,当我们必须为saveItem
编写单元测试已经调用重载方法为addNewItem
的方法时,如果您使用了常规方法来创建模拟,那么您的回答将不会返回您的内容希望在回答对象回归。
@RunWith(PowerMockRunner.class)
@PrepareForTest({ })
public class ItemTest{
@Test
public void testSaveItem() throws Exception {
//create a real object of MainServiceImpl
MainServiceImpl mainService = new MainServiceImpl();
//create a normal way for a mocking object
AService aService = Mockito.mock(AService.class);
// Add mock object to MainServiceImpl instance
ReflectionTestUtils.setField(mainService, "aService", aService);
//Mock when aService call to addNewItem() method
PowerMockito.when(aService , "addNewItem", Mockito.anyString(), Mockito.anyString()).then(new Answer<ReturnObject>() {
@Override
public ReturnObject answer(InvocationOnMock invocation) throws Throwable {
return new ReturnObject("saveOK");
}
});
ReturnObject returnObj = mainService.saveItem("Book", "Code123");
Assert.assertNotNull(returnObj);
}
}
尝试使用下面的testSaveItem替换上面的testSaveItem,然后成功:
@Test
public void testSaveItem() throws Exception {
//create a real object of MainServiceImpl
MainServiceImpl mainService = new MainServiceImpl();
//create a special way for a mocking object by add
//the answer at create the mock object
final Answer<ReturnObject> answer = new Answer<ReturnObject>() {
@Override
public ReturnObjectanswer(final InvocationOnMock invocation) throws Throwable {
return new ReturnObject("saveOK");
}
};
AService aService = Mockito.mock(AService.class, answer);
// Add mock object to MainServiceImpl instance
ReflectionTestUtils.setField(mainService, "aService", aService);
//Mock when aService call to addNewItem() method
PowerMockito.when(aService , "addNewItem", Mockito.anyString(), Mockito.anyString()).then(new Answer<ReturnObject>() {
@Override
public ReturnObject answer(InvocationOnMock invocation) throws Throwable {
return new ReturnObject("saveOK");
}
});
ReturnObject returnObj = mainService.saveItem("Book", "Code123");
Assert.assertNotNull(returnObj);
}
答案 3 :(得分:0)
就像在嘲讽github上提到的那样:
这似乎与第二次致电有关。我找不到正在发生的事情,但是第二次没有尝试添加模拟逻辑时,它只是调用了该方法。 替换为doReturn()。when()有效。
>>> import numpy as np
>>> np.random.seed(5)
>>> np.random.rand()
0.22199317108973948 # (1)
>>> np.random.rand()
0.8707323061773764 # (2)
>>> np.random.seed(5) # re-seed
>>> np.random.rand()
0.22199317108973948 # same as (1)
>>> np.random.seed(5)
>>> np.random.rand()
0.22199317108973948 # same as (1) again
>>> np.random.rand()
0.8707323061773764 # same as (2)
https://github.com/mockito/mockito/issues/1496#issuecomment-423310950 DavidTanner