5

I have a class with method:

class URAction {
      public List<URules> getUrules(Cond cond, Cat cat) {
             ...
      } 
}

I want to create its mock:

@Mock
URAction uraMock;

@Test
public void testSth() {
    Cond cond1;
    Cat cat1;
    List<URule> uRules;

    // pseudo code
    // when uraMock's getUrules is called with cond1 and cat1
    // then return uRules
}

The problem is I can make the mock return uRules for only one argument:

 when(uraMock.getUrules(argThat(
        new ArgumentMatcher<Cond> () {

            @Override
            public boolean matches(Object argument) {
                Cond cond = ((Cond) argument);
                 if (cond.getConditionKey().equals(cond1.getConditionKey()) 
                     return true;
                 return false;
            }

        }
    ))).thenReturn(uRules);

Not sure how to pass the second argument ie Cat in the when call above.

Any help would be greatly appreciated.

Thanks

user1539343
  • 1,569
  • 6
  • 28
  • 45
  • one solution would be to use `when(uraMock.getUrules(any(Cond.class), any(Cat.class).thenAnswer(new Answer() { })`, and check args in the implemented answer. see http://site.mockito.org/mockito/docs/current/org/mockito/stubbing/Answer.html –  Nov 02 '16 at 06:35
  • That seems to be a viable solution. How can I mark this as answer? It is only in the comment. – user1539343 Nov 02 '16 at 15:19
  • Let's do this: add an answer based on my comment and accept it, this could give you some rep. ;) –  Nov 02 '16 at 16:24
  • But this answer doesn't check if the parameter is the same as originally passed. It just checks for any object. The answer I've provided below validates that – Gunith D Nov 02 '16 at 23:54
  • @user1539343 just use: `when(uraMock.getUrules(cond1,cat1)).thenReturn(uRules);` This is as simple as the one in the first comment and also checks the params passed – Mindaugas Nov 03 '16 at 13:51
  • @Mindaugas, this will work only if the equality conditions meet for the Cond and Cat ie there are equals method that match the arguments. – user1539343 Nov 03 '16 at 15:38
  • 1
    @Gunith, please check the link RC provided. – user1539343 Nov 03 '16 at 15:38

1 Answers1

4

Could you try adding another argThat(argumentMatcher) for the second argument matcher?

Also, I find it's better to not have the anonymous class defined as a method and not inline as you have done. Then you could use it for verify() as well.

Your methods should look like this

ArgumentMatcher<Cond> matcherOne(Cond cond1){
   return new ArgumentMatcher<Cond> () {
        @Override
        public boolean matches(Object argument) {
            Cond cond = ((Cond) argument);
            if (cond.getConditionKey().equals(cond1.getConditionKey()) 
               return true;
            return false;
        }
   }
}

ArgumentMatcher<OtherParam> matcherTwo(OtherParam otherParam){
   return new ArgumentMatcher<OtherParam> () {
        @Override
        public boolean matches(Object argument) {
            OtherParam otherParam = ((OtherParam) argument);
            if (<some logic>) 
               return true;
            return false;
        }
   }
}

Then you could call your methods like this,

when(uraMock.getUrules(argThat(matcherOne(cond1)), argThat(matcherTwo(otherParam)))).thenReturn(uRules);

Then, as I you could call verify, to check if your when method really got called

verify(uraMock).getUrules(argThat(matcherOne(cond1)), argThat(matcherTwo(otherParam)));

If you don't care about the other param, you can do,

when(uraMock.getUrules(argThat(matcherOne(cond1)), argThat(any()))).thenReturn(uRules);

For more details see: http://site.mockito.org/mockito/docs/current/org/mockito/stubbing/Answer.html

Hope that's clear.. Good luck!

Gunith D
  • 1,843
  • 1
  • 31
  • 36