easyforgood / mockito

Automatically exported from code.google.com/p/mockito
0 stars 0 forks source link

Deep refEq matcher for verifying calls on mocks #382

Open GoogleCodeExporter opened 8 years ago

GoogleCodeExporter commented 8 years ago
I know the following enhancement request is a result of bad code design, but I 
find myself often in the following situation.

In our code we're depending on some third party library, which exposes some 
interfaces. Each interface has methods with at most one parameter. These 
parameters can sometimes be complex objects, which hold other objects, which on 
their turn hold other objects.

When testing our application, we want to verify we've called the methods on the 
third party interfaces using the correct contents. For simple POJO like 
objects, this can be achieved using Mockito's Matchers.refEq method. It creates 
an object that is reflection equal to the parameter object. But only up to one 
level. So only for the first level of members. If the object contains other 
objects that don't have equals() implemented, these are ignored and using 
Mockito.verify with the returned object fails.

Example:

Assume the following class:

class Car {
  public String brand;
  public Person owner;
}

class Person {
  public String name;
}

and assume the following interface

interface CarManager {
  void addCar(Car car);
}

In some test of some class that uses CarManager, I would typicaly want to check 
that addCar is being called with the correctly filled in Car, all the way down 
to the Person object. If it weren't for the Person object, I could've done:

Car car = new Car();
car.brand = "Somebrand";
verify(carManagerMock).addCar(refEq(car));

but in fact, I want to do something like:

Car car = new Car();
car.brand = "Somebrand";
car.person = new Person("Pete Petersen");
verify(carManagerMock).addCar(deepRefEq(car));

I might be mistaking, but I don't think anything like this is possible in 
Mockito at the moment and it would be a very welcome enhancement.

Original issue reported on code.google.com by tonnitie...@gmail.com on 3 Oct 2012 at 12:18

GoogleCodeExporter commented 8 years ago
In general, I would recommend using an ArgumentCaptor and trying to make the 
test assert only on the state that is interesting VS interrogating the entire 
object via reflection.

If the construction of the complex parameter happens in a mocked method it can 
be refactored out to a separate factory.

Thanks a lot for feedback. I don't think we'll schedule work on deep ref equals 
in near time. This might be a good case for a separate library that contains 
reflection-powered Mockito matchers. You can also look up the web, perhaps 
there are already some hamcrest matcher implementations that solve your use 
case.

Hope that helps!

Original comment by szcze...@gmail.com on 12 Oct 2012 at 7:41

GoogleCodeExporter commented 8 years ago
Thanks. I think it helps very much. It's exactly what I need. I wasn't aware of 
ArgumentCaptors in Mockito. I will try it out first thing next Monday. :-)

Original comment by tonnitie...@gmail.com on 12 Oct 2012 at 7:48

GoogleCodeExporter commented 8 years ago
Using ArgumentCaptor and Fest-Assert is fantastic :)

Plus they are on github, and they listen to their users as well !

Original comment by brice.du...@gmail.com on 12 Oct 2012 at 8:00

GoogleCodeExporter commented 8 years ago

Original comment by brice.du...@gmail.com on 23 Oct 2012 at 8:51

GoogleCodeExporter commented 8 years ago

Original comment by brice.du...@gmail.com on 2 Dec 2012 at 10:16