简体   繁体   中英

how test returned object from a mocked dependency that accepts two arguments inside the mocked object?

I couldn't find any post related to my problem. I'm using Mockito and I want to test the behavior inside a controller. I think the core of the problem is that I'm not using Mockito correctly when I send in two arguments to the mocked interface. It works fine if I only send in one argument. I don't think the fact that I'm also using Spring mock mvc has anything to do with this.

I have an interface MyService :

public MyObject doSomeDoggyStuff(long id, SomeOtherObject soo);

The purpose of the interface is to do things and return MyObject if it was successful. If it can't find the object then just return null.

I have a controller 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)'
     }
  }

My test class looks like this:

Public MyControllerTest <snip>

  @Mock
  private MyService myServiceMock;

  @InjectMocks
  private MyController myController;

The relevant logic of test method looks this.

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();

The problem I'm having is that I expect in this scenario that when it tests MyController that on the line: MyObject result = this.myService.doSomeDoggyStuff(id, toy);

result should be the myObj I set up in the thenReturn but it's always set to null. I have other methods in my service that just accepts one argument and it works fine. I can't grasp what I need to do differently when I send in two arguments using Mockito.

If I understand your requirements correctly you should use the mock like this:

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

The way you have written your code, the mock will return myObj only when called with the Toy object which you instantiated it with, which is never since Spring will instantiate the class on it's own. The problem doesn't have anything to do with the number of arguments.

If however you want to test for a specific Toy and not just any instance of it, you will need to add an equals (and to be correct with the spec, a hashCode ) method so mockito can match the Toys. In the absence of any equals method, the references are checked and of couse those are not equals because the instances are not the same.

You need to either implement equals in your Toy or use ArgumentCaptor to check details of the object passed. Otherwise (like geoand already managed to mention) you compare the references.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM