Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Mockito Allow different argument types to mock overloaded method

For JUnit testing I want to mock an overloaded method. There is no need to implement several methods in the mockbuilder though. I want to do something like this:

Mockito.when(mock.getSomeInfo(Mockito.any(ArgumentType1.class) OR Mockito.any(ArgumentType2.class), Mockito.any(ArgumentType3.class))).then(new Answer<AnswerType>() {..}

I know it doesn't work with the OR statement, but is there another way to do this in Mockito?

like image 723
Chry007 Avatar asked Mar 31 '15 09:03

Chry007


People also ask

What are the different approaches that we can use to mock objects using Mockito?

The Mockito framework provides a variety of methods such as mock(), verify(), when(), etc., used to test Java applications. Using these predefined methods makes testing very easy.

What does @mock do in Mockito?

Mockito @Mock Annotation We can mock an object using @Mock annotation too. It's useful when we want to use the mocked object at multiple places because we avoid calling mock() method multiple times. The code becomes more readable and we can specify mock object name that will be useful in case of errors.

What does stubbing mean in Mockito?

A stub is a fake class that comes with preprogrammed return values. It's injected into the class under test to give you absolute control over what's being tested as input. A typical stub is a database connection that allows you to mimic any scenario without having a real database.

Does Mockito mock call real method?

Mockito allows us to partially mock an object. This means that we can create a mock object and still be able to call a real method on it. To call a real method on a mocked object we use Mockito's thenCallRealMethod().


2 Answers

As mentioned on the mockito github:

It looks like this has to do with calling when the second time. I couldn't find what was going on, but the second when doesn't attempt to add the mock logic, it just calls the method. Replacing with doReturn().when() works.

    doReturn(expected1).when(overloadedMethods).getString(any());
    doReturn(expected2).when(overloadedMethods).getString(any(), any());

https://github.com/mockito/mockito/issues/1496#issuecomment-423310950 DavidTanner

like image 153
Nayeem Avatar answered Sep 23 '22 09:09

Nayeem


You can do this with a custom matcher.

Warning: Be reasonable with using complicated argument matching, especially custom argument matchers, as it can make the test less readable. Sometimes it's better to implement equals() for arguments that are passed to mocks (Mockito naturally uses equals() for argument matching). This can make the test cleaner.


public class TypeOrMatcher extends ArgumentMatcher<Object> {

  private final List<Class<?>> clazzes;

  public TypeOrMatcher(Class<?>...clazzes) {
    this.clazzes = new ArrayList<Class<?>>(clazzes);
  }

  public boolean matches(Object actual) {
    if (actual == null) {
      return false;
    }
    Class<?> actualClass = actual.getClass();
    for (Class<?> clazz : clazzes) {
      if (clazz.isAssignableFrom(actualClass) {
        return true;
      }
    }
    return false;
  }
}

TypeOrMatcher isTypeOneOrTwo = new TypeOrMatcher(
    ArgumentType1.class, ArgumentType2.class); 

Some mockObj = mock(Some.class);
when(mockObj.someMethod(argThat(isTypeOneOrTwo), any(ArgumentType3.class))
    .thenReturn(true);
like image 43
dting Avatar answered Sep 20 '22 09:09

dting