0

我找不到任何与我的问题相关的帖子。我正在使用 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);

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

4

2 回答 2

1

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

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

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

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

于 2014-06-20T14:28:40.273 回答
0

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

于 2014-06-20T14:44:17.517 回答