我有4个课程让我们说A,B,C,D各自调用另一个方法。
现在我嘲笑了A类,想要使用mockito模拟一个方法
A a = Mockito.mock(A.class);
并希望在递归方法调用(如
)上获得“foo” a.getB().getC().getD()
应该返回"foo"
我试过
当(a.getB()GETC()GETD()。)thenReturn( “富”);
但得到了nullPointerException
然后我试了
doReturn( “富”)时(a.getB()GETC()GETD());
然后我得到org.mockito.exceptions.misusing.UnfinishedStubbingException:
我知道我可以创建B,C和D的对象,或者甚至可以编写类似
的对象B b = mock(B.class)或A.setB(new B())
等等。
但我不能一次性做到这一点? 任何帮助将不胜感激。
答案 0 :(得分:40)
来自评论:
添加RETURNS_DEEP_STUBS就可以了:
{{1}}
答案 1 :(得分:11)
Abhijeet的技术答案在技术上是正确的,但重要的是要理解:你应该不这样做。
您的生产"代码严重违反Law of Demeter:您的A类不知道必须获得B才能获得C才能获得D.
这只会导致所有这些类之间的超紧密耦合。不是个好主意。
从这个意义上说:你应该看到这样一个事实:你需要在这里做一些特殊的事情来让你的测试工作,这实际上表明你的生产代码做了超出正常的事情。
所以,而不是"修复"您的测试设置,请考虑解决真正的问题。这就是生产代码的设计!
对于记录:getB()。getC()。getD()不是"递归"呼叫;它更像是一个流畅的"方法调用的链接。如上所述:不是一件好事。
答案 2 :(得分:0)
尝试创建每个嵌套对象的模拟,然后模拟每个对象调用的单个方法。
如果目标代码如下:
public Class MyTargetClass {
public String getMyState(MyClass abc){
return abc.getCountry().getState();
}
}
然后为了测试这一行,我们可以为每个单独的嵌套对象创建模拟,如下所示:
public Class MyTestCase{
@Mock
private MyTargetClass myTargetClassMock;
@Mock
private MyClass myclassMockObj;
@Mock
private Country countryMockObj;
@Before
public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
}
@Test
public void test01(){
when(myclassMockObj.getCountry()).thenReturn(countryMockObj);
when(countryMockObj.getState()).thenReturn("MY_TEST_STATE");
Assert.assertEquals("MY_TEST_STATE", myTargetClassMock.getMyState(myclassMockObj));
}
}