【问题标题】:Using Mockito: Argument(s) are different! Wanted: Actual invocation has different arguments:使用 Mockito:参数不同!需要:实际调用有不同的参数:
【发布时间】:2018-01-26 05:40:39
【问题描述】:

当我这样运行 JUnit 测试时:

@Test
public void insertSignRewardTest() throws Exception{
    SignRewardRequest srr = new SignRewardRequest();
    srr.setBeginTime(new Date().toLocaleString());
    srr.setPoint(21);
    srr.setUseableId("123");
    srr.setEndTime(new Date().toLocaleString());

    SimpleDateFormat sFormat = new SimpleDateFormat("yyyy-MM-dd");
    PointRewardDeploy pointRewardDepoly = new PointRewardDeploy();
     Date reward_begin_date = new Date();
     Date reward_end_date = new Date();
     reward_begin_date = sFormat.parse(srr.getBeginTime());
     reward_end_date = sFormat.parse(srr.getEndTime());
    pointRewardDepoly.setPoint_source_type(Long.valueOf(PointSourceType.SIGNED.getValue().toString()));
     pointRewardDepoly.setCreate_time(new Date());
     pointRewardDepoly.setUpdate_time(new Date());
     pointRewardDepoly.setReward_begin_date(reward_begin_date);
     pointRewardDepoly.setReward_end_date(reward_end_date);
     pointRewardDepoly.setStatus(1l);
     pointRewardDepoly.setReward_point(srr.getPoint());

    List<PointRewardDeploy> listPointRewardDeploy = new ArrayList<PointRewardDeploy>();
    listPointRewardDeploy.add(pointRewardDepoly);

    CommonListResult<PointRewardDeploy> cr = new CommonListResult<PointRewardDeploy>();
    cr.setCode("success");
    cr.setMsg("ok");
    cr.setSuccess(true);
    List<PointRewardDeploy> date = new ArrayList<>();
    date.add(pointRewardDepoly);
    cr.setData(date);

    ObjectMapper mapper = new ObjectMapper();
    String str = mapper.writeValueAsString(srr);
    when(pointAccountService.savePointRewardDeploy(listPointRewardDeploy)).thenReturn(cr);

    this.mockMvc.perform(MockMvcRequestBuilders.post("/api/sign/signPrizeDraw/insertSignReward")
            .contentType(MediaType.APPLICATION_JSON)
            .content(str))
    .andDo(print())
    .andExpect(status().isOk());

    Assert.assertEquals(true, cr.getSuccess()); 
    verify(pointAccountService,times(1)).savePointRewardDeploy(refEq(listPointRewardDeploy));
}

我使用org.mockito.Matchers.refEq at:

verify(pointAccountService,times(1))
    .savePointRewardDeploy(listPointRewardDeploy) 

verify(pointAccountService,times(1))
    .savePointRewardDeploy(refEq(listPointRewardDeploy))

然后运行它,它通过了测试,但是打印出来的信息是空的,比如:

MockHttpServletRequest:
HTTP Method = POST
Request URI = /api/sign/signPrizeDraw/insertSignReward
Parameters = {}
Headers = {Content-Type=[application/json]}
Handler:
Type = com.yirendai.mplatform.sign.controller.UserInfoListController
Method = public 
Async:
Async started = false
Async result = null

Resolved Exception:
Type = null

ModelAndView:
View name = null
View = null
Model = null

FlashMap:
Attributes = null

MockHttpServletResponse:
Status = 200
Error message = null
Headers = {}
Content type = null
Body = 
Forwarded URL = null
Redirected URL = null
Cookies = []

我的问题:打印信息正确吗?我认为它不正确,但不知道如何解决它。谢谢你帮助我。

【问题讨论】:

  • 这里有一些一般性的(如果可能是不请自来的)反馈给您。对我来说,那个测试太长了。我认为测试中的很多设置都是代码味道,这表明职责没有很好地划分。在您的 sn-p 中发现测试对象(或 SUT)并不容易——也许更大的上下文(文件名?)会有所帮助。我力求测试方法在“Arrange, Act, Assert”之间最多可能有六七行。比这长得多,我发现这样离开太贵了。

标签: java spring unit-testing spring-mvc mockito


【解决方案1】:

打印输出在我看来是正确的,但如果没有看到映射到 /api/sign/signPrizeDraw/insertSignReward 的控制器方法,很难确定,具体来说:该方法返回的内容。

如果您希望 body 包含在打印输出中,那么:

  • body 未打印在请求中
  • 只有在响应中包含body 时,才会在响应中打印body

请记住,print() 不是 MVC 层的正式输出,它只是一个(有时)有用的诊断工具。只要你测试...

  • 状态码
  • 响应内容和类型(如果控制器方法返回某些内容)
  • 任何副作用,形式为对控制器下层的验证或期望(例如服务或存储库调用)

...那么我认为您的 MockMvc 测试用例就足够了,您无需关心print() 输出的结果。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-11-28
    • 1970-01-01
    • 1970-01-01
    • 2011-12-26
    相关资源
    最近更新 更多