easyforgood / mockito

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

Generic Argument and Return type method mock #362

Closed GoogleCodeExporter closed 8 years ago

GoogleCodeExporter commented 8 years ago
What steps will reproduce the problem?
1. public <T> T find(T t);
2. code need to be tested:
   public void test(int companyId, int userId) {
     Company exampleCompany = new Company(companyId);
     Company company = service.findByExample(exampleCompany);
     User exampleUser = new User(userId);
     User user = service.findByExample(exampleUser);
     company.xxx();
     user.yyy();
   }
3. test code :
  @Spy @InjectMocks
  TestClass testClass;

  @Mock
  Service service;

  Company company = new Company();
  company.setXXX(xxx);
  company.setYYY(yyy);
  User user = new User();
  user.setZZZ(zzz);

  // mock method return my company
  doReturn(company).when(service).findByExample(any(Company.class));
  // mock method return my user
  doReturn(user).when(service).findByExample(any(User.class));

What is the expected output? What do you see instead?
  expected: first findByExample return my company, second findByExample return my user
    actual: second mock override first mock, ClassCastException while find company.

What version of the product are you using? On what operating system?
  1.9.0   windows 7 64bit

Please provide any additional information below.
  I have read source code, org.mockito.internal.matchers.Any.matches(Object actual) just return true, and Any doesn't contain class info, this make generic argument method can not be mock multi-times. I think any() means any instance of some class, but for different classes, this should be different. For same class, later mock should override any mocks before it.

Original issue reported on code.google.com by xpj...@gmail.com on 10 Aug 2012 at 5:45

GoogleCodeExporter commented 8 years ago
Hi,

Your code is incorrect in several ways:

 - the any() matcher does not check for types, this wasn't clear in the javadoc, though it has been updated. http://docs.mockito.googlecode.com/hg/1.9.0/org/mockito/Matchers.html
You should use instead the isA() matcher.

 - your mocking is incorrect, as the any() matchers do not uses the type, which means that the last stub replaces the first. i.e. service.findByExample will always return a User.

So you should use instead isA() matcher and it will work as expected.

Alternatively if you want to stub consecutive calls you should use the 
documented way : 
http://docs.mockito.googlecode.com/hg/1.9.0/org/mockito/Mockito.html#10
Or with your syntax style :
doReturn(company).doReturn(user).when(service).findByExample(any());

 - You should avoid using both @Spy and @InjectMocks on the same class, it's possible but I would advise against as it means you have some flaws in your design to require to both spy and inject mocks in the tested object.

Original comment by brice.du...@gmail.com on 20 Aug 2012 at 2:20

GoogleCodeExporter commented 8 years ago
very thanks, Brice.

Original comment by xpj...@gmail.com on 24 Aug 2012 at 5:37

GoogleCodeExporter commented 8 years ago
you are welcome :)

Cheers,
Brice

Original comment by brice.du...@gmail.com on 24 Aug 2012 at 8:36

GoogleCodeExporter commented 8 years ago

Original comment by brice.du...@gmail.com on 3 Sep 2012 at 10:00