Mockito:验证是否调用了Spring Data JPA delete()方法

 拐久了_618 发布于 2023-02-06 19:05

所以,我对单元测试相对较新,特别是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) - 如果是这样,请随时给我一个提示:)

在这里获得一些帮助会很棒!提前致谢.

1 个回答
  • 你的方法会调用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注释而不是实例化您的服务并使用反射注入存储库.

    2023-02-06 19:08 回答
撰写答案
今天,你开发时遇到什么问题呢?
立即提问
热门标签
PHP1.CN | 中国最专业的PHP中文社区 | PNG素材下载 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有