所以,我对单元测试相对较新,特别是mockito,我试图弄清楚如何在Spring WebMVC中测试以下场景:
这是我的服务类(简化):
@Service public class MyServiceImpl implements MyService { @Resource private MyCrudRepository myCrudRepository; /** * Method to delete(!) an entry from myTable. * */ @Transactional public void removeTableEntry(Long entryOid, String userId) throws Exception { if (myCrudRepository.findOne(entryOid) != null) { myCrudRepository.delete(entryOid); log.info("User ID: " + userId + " deleted Entry from myTable with Oid " + entryOid + "."); } else { log.error("Error while deleting Entry with Oid: "+ entryOid + " from User with ID: " + userId); throw new Exception(); } } }
这里我称之为Spring Data JPA crudrepository的"内置"delete方法,这意味着存储库本身没有自定义实现(使用OpenJPA).
这是我简化的测试类:
@RunWith(MockitoJUnitRunner.class) public class MyServiceImplTest { final String USERID = "Testuser"; MyServiceImpl myService; @Mock MyCrudRepository myCrudRepository; @Before public void setUp() { myService = new MyServiceImpl(); ReflectionTestUtils.setField(myService, "myCrudRepository", myCrudRepository); } //works (as expected? not sure) @Test(expected = Exception.class) public void testRemoveSomethingThrowsException() throws Exception { doThrow(Exception.class).when(myCrudRepository).delete(anyLong()); myService.removeSomething(0l, USERID); } //does not work, see output below @Test public void testRemoveSomething() throws Exception { verify(myCrudRepository, times(1)).delete(anyLong()); myService.removeSomething(0l, USERID); } //... }
所以,我尝试验证删除是否被调用testRemoveSomething()
,但我得到以下输出:
Wanted but not invoked: myCrudRepository.delete(); -> at myPackage.testRemoveSomething(MyServiceImplTest.java:98) Actually, there were zero interactions with this mock.
而且我几乎没有想法为什么,说实话(考虑一下@Transactional
,或许?但这并没有让我得到解决方案,但是).可能是我在这里完全错了(建筑,dunno) - 如果是这样,请随时给我一个提示:)
在这里获得一些帮助会很棒!提前致谢.
你的方法会调用findOne(),检查是否返回了什么,然后调用delete().所以你的测试应该首先确保findOne返回一些东西.否则,模拟存储库的findOne()方法默认返回null.此外,您应该验证调用在执行后是否已执行.不是之前.
@Test public void testRemoveSomething() throws Exception { when(myCrudRepository.findOne(0L)).thenReturn(new TableEntry()); myService.removeTableEntry(0l, USERID); verify(myCrudRepository, times(1)).delete(0L); }
此外,您应该使用@InjectMocks
注释而不是实例化您的服务并使用反射注入存储库.