【问题标题】:In Java, How to test void method in Junit Mockito with assertion?在 Java 中,如何使用断言测试 Junit Mockito 中的 void 方法?
【发布时间】:2020-03-09 12:28:18
【问题描述】:

如何在 Mockito 中使用 assertSame 或 assertEquals 测试 void 方法。我只能进行验证。 我收到声纳或 PMD 规则违规 - “JUnit 测试应包括 assert() 或 fail()”。 下面是我的带有测试类的示例类。

    @Service
    public class MyServiceImpl implements IService {

        @Autowired
        private IDyDBDAO dyDBDAO;

        @Override
        public void update() {
            dyDBDAO.save(getDetailData());
        }

        @Override
        public List<Detail> getCurrentDetail() {
            return getDetails(dyDBDAO.findAll());
        }

        private List<Detail> getDetails(Iterable<Detail> details) {
            ...blah...

        }

        private String getPlace(){
        Places p = Places.getPlace();//static

        return p == null? PlacesUtil.getName("DH"): p.getName;
        }
        private Detail getDetailData() {
            Detail d = new Detail();
            d.setName("blah");
        d.setDesc("fsdfsdfdsf");
        d.setPlace(getPlace());
            return d;
        }
    }

    @RunWith(PowerMockRunner.class)
    @PrepareForTest({Places.class, PlacesUtil.class})
    public class MyServiceImplTest {

        @InjectMocks
        private MyServiceImpl myServiceImpl;

        @Mock
        private IDyDBDAO dyDBDAO;

        @Test
        public void testGetCurrentDetail() {
            given(dyDBDAO.findAll()).willReturn(getMockDetails());
            assertSame(myServiceImpl.getCurrentDetail().size(), 2);
        }

        @Test
        public void testUpdate() {
            PowerMockito.mockStatic(Places.class);
            // first update  , second update -us-west-2 will update
            given(Places.getPlace()).willReturn(PlacesUtil.getName("UH"))
                    .willReturn(null);       
            myServiceImpl.syncStatus();
            // update again with DH
            myServiceImpl.syncStatus();
            verify(dyDBDAO, times(2)).save(any(Detail.class));
        // how to assert checking here
        }

        private Iterable<Detail> getMockDetails() {
            Detail d1 = new Detail();
            d1.setName("blah");
        d1.setDesc("fsdfsdfdsf");
        d1.setPlace("sdfsdf");

            Detail d2 = new Detail();
            d2.setName("blahblah1");
        d2.setDesc("e345345");
        d2.setPlace("8907j");

            List<Detail> listOfDetail = new ArrayList<>();
            listOfDetail.add(eps1);
            listOfDetail.add(eps2);
            return listOfDetail;
        }

    }

【问题讨论】:

  • 这里什么方法无效?请出示minimal reproducible example
  • 你不能。然后update 方法似乎没有任何重要的逻辑可以测试。
  • 一个void 方法做任何有意义的事情都必须通过副作用(输入参数,持久状态)工作。你需要断言副作用。

标签: java mockito powermockito


【解决方案1】:

您需要捕获传递给 dao save 方法的值。为此使用 mockito 的 ArgumentCaptor。然后断言该值。 大致如下:

ArgumentCaptor<Detail> captor = ArgumentCaptor.forClass(Detail.class);
verify(dyDBDAO, times(2)).save(captor.capture());
Detail detail1 = captor.getValues().get(0)
assertEquals(expectedDetail, detail1)

【讨论】:

  • 如何在这里给出expectedDetail。 expectedDetail obj 将如何创建?
  • 只需实例化它,并将其属性设置为测试所期望的任何值。细节预期细节 = 新细节();
  • 谢谢。但是如果我用新实例创建,它在 assertEquals 中的相同
  • 这就是你断言测试中创建的预期值和被测试类创建(然后捕获)的实际值是相同的测试的重点
【解决方案2】:

我假设您需要测试的void 方法是update in MyServiceImpl

首先,你可以验证dyDBDAO.save()是否被调用。

Mockito.verify(dyDBDAO).save(Mockito.anyList...);

其次,您可以通过检索它们并与来自getMockDetails 的输入进行比较来检查数据库中修改或创建的记录。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-02-17
    • 2021-11-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多