【问题标题】:how test returned object from a mocked dependency that accepts two arguments inside the mocked object?如何测试从接受模拟对象内的两个参数的模拟依赖项返回的对象?
【发布时间】:2014-06-20 13:54:07
【问题描述】:

我找不到任何与我的问题相关的帖子。我正在使用 Mockito,我想测试控制器内部的行为。我认为问题的核心是当我向模拟接口发送两个参数时,我没有正确使用 Mockito。如果我只发送一个参数,它就可以正常工作。我认为我也在使用 Spring mock mvc 的事实与此无关。

我有一个接口MyService

public MyObject doSomeDoggyStuff(long id, SomeOtherObject soo);

接口的目的是做事,如果成功则返回MyObject。如果找不到对象,则返回 null。

我有一个控制器MyController

@RestController
@RequestMapping(value = "/dogs")
public MyController
<snip>

 @RequestMapping(method = RequestMethod.POST, value = "/{id}/toys/{toy}")
  ResponseEntity<MyObject> doDoggyStuff(@PathVariable Long id, @RequestBody Toy toy) {
    MyObject result = this.myService.doSomeDoggyStuff(id, toy);
    if(result == null) {
       return new ResponseEntity("errorinfo", HttpStatus.NOT_FOUND);
     }
    else {
      return new ResponseEntity<MyObject>(result,HttpStatus.CREATED)'
     }
  }

我的测试类如下所示:

Public MyControllerTest <snip>

  @Mock
  private MyService myServiceMock;

  @InjectMocks
  private MyController myController;

测试方法的相关逻辑是这样的。

MyObject myObj = new MyObject();
Toy toy = new Toy();

when(myServiceMock.doSomeDoggyStuff(1, toy)).thenReturn(myObj);
mockMvc
    .perform(
        post("/dogs/{id}/toys/{toys}", 1, toy).contentType(
            TestUtil.APPLICATION_JSON_UTF8).content(
            TestUtil.convertObjectToJsonBytes(toy))).andExpect(status().isCreated())
    .andReturn();

我遇到的问题是,我希望在这种情况下,当它测试 MyController 时:MyObject result = this.myService.doSomeDoggyStuff(id, toy);

result 应该是我在 thenReturn 中设置的 myObj,但它始终设置为 null。我的服务中有其他方法只接受一个参数并且工作正常。当我使用 Mockito 发送两个参数时,我无法理解我需要做哪些不同的事情。

【问题讨论】:

  • 您是否尝试调试实际传递给服务方法调用的内容?可能是在 Toy 类中缺少 equals 实现。你能发布玩具类代码吗?

标签: java unit-testing mockito mockmvc


【解决方案1】:

如果我正确理解您的要求,您应该像这样使用模拟:

when(myServiceMock.doSomeDoggyStuff(eq(1), any(Toy.class))).thenReturn(myObj);

按照您编写代码的方式,只有在使用您实例化它的 Toy 对象调用时,模拟才会返回 myObj,这是因为 Spring 不会自己实例化该类。这个问题与参数的数量没有任何关系。

但是,如果您想测试特定的 Toy 而不仅仅是它的任何实例,您将需要添加一个 equals(并且要符合规范,一个 hashCode)方法,以便 mockito 可以匹配玩具。在没有任何 equals 方法的情况下,会检查引用,当然这些引用不相等,因为实例不相同。

【讨论】:

  • 这种方式测试不是测试 Magnus 想要测试的东西 - 它会通过任何玩具对象。我认为问题在于 Toy 中缺少 equals 实现。
  • @macias 你很可能是对的!这就是我添加第一句话的原因:)。我会相应地更新答案
  • 谢谢你们!这很好用。 Mockito 很棒,但有时在某些情况下要让语法正确有点令人困惑。
【解决方案2】:

您需要在 Toy 中实现 equals 或使用 ArgumentCaptor 检查传递对象的详细信息。否则(就像 geoand 已经设法提到的)你比较参考。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-01-08
    • 1970-01-01
    相关资源
    最近更新 更多