问题:我有a级
class A {
@Autowired
EdocumentDAO eDocumentDAO;
public void createDocument(DocumentType docType)
{
String DocID= saveIndocRepo();//To be Mocked
docType.setID(DocID);
isSaved = eDocumentDAO.save()//Autowired
}
private String saveIndocRepo()
{
//Code to save in Repo in another platform and return the DOC_ID
}
}
我的A_Test类
@ContextConfiguration({ "classpath:test-beans.xml" })
@RunWith(SpringJUnit4ClassRunner.class)
@ActiveProfiles("test")
class A_test {
A a = Mockito.spy(new A());
Mockito.doReturn("DOC_ID").when(a).saveIndocRepo();
a.createDocument(docType);
}
要求:我有一个方法saveIndocRepo()
,它与外部服务交互并将文档保存在他们的repo中。所以这需要嘲笑。
其在CCD_ 2中被调用并且应当返回模拟值。收到DocID后,其他文档详细信息将保存到数据库中(我已经为其配置了一个Derby内存数据库)。EdocumentDO在弹簧实例化的Autowiring上工作。
问题:当我尝试模拟该方法(saveInDocRepo)时,它的Moked成功了,但Autowiring失败了。这导致JUnit失败。当我删除mocking时,自动布线就完美地执行了。
我缺少什么吗。或者我的方法不正确。专家-请提供适当的解决方案。
感谢大家的帮助。
解决方案:
@ContextConfiguration({ "classpath:test-beans.xml" })
@RunWith(SpringJUnit4ClassRunner.class)
@ActiveProfiles("test")
@Spy
@InjectMocks
A a = new A();
@Autowired
@Spy
EdocumentDAO eDocumentDAO;
class A_test {
Mockito.doReturn("DOC_ID").when(a).saveIndocRepo();
a.createDocument(docType);
}
现在,当调用createDocument()方法时,saveInDocRepo()被模拟为返回"DOC_ID",并且eDocumentDAO.save()非常有效。它的@Spy是用来部分嘲讽的,拯救了这一天。
您必须模拟接口,而不是类本身。使用要模拟的类的公共方法创建一个接口。
在上面的示例中,您正在监视A
,但A
依赖于EdocumentDAO
。你也得嘲笑这个班。
@Mock
EdocumentDAO edocumentDAOMock;
或者,我最喜欢的Spring方式,因为您可以实现模拟行为:
@Bean
private EdocumentDAO getEdocumentDAOMock() {
return mock(EdocumentDAO.class);
}
此外,由于您使用的是Spring,因此不能使用new A()
,必须使用Spring来实例化Bean,否则自动连接的注释将不起作用。
您可以使用mockito的简写注入,而不依赖Spring:
class ATest {
@Rule public MockitoRule mockitoRule = MockitoJUnit.rule();
@Mock EdocumentDAO dao;
@InjectMocks A a;
@Test
public void the_test() {
doReturn("DOC_ID").when(dao).saveIndocRepo();
a.createDocument(docType);
}
}
请注意,这是伪代码,因为我现在不能使用IDE