Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Mockito when method not working

Tags:

java

mockito

I am using mockito as mocking framework. I have a scenerio here, my when(abc.method()).thenReturn(value) does not return value, instead it returns null.

public class DQExecWorkflowServiceImplTest {
@InjectMocks
DQExecWorkflowServiceImpl dqExecWorkflowServiceImpl = new DQExecWorkflowServiceImpl();
@Mock
private DQUtility dqUtility;
@Mock
private DqExec dqExec;
@Mock
private DqCntlDefn dqCntlDefn;
@Mock
private DqCntlWfDefn dqCntlWfDefn;
@Mock
private DqCntlWfDefnTyp dqCntlWfDefnTyp;
@Mock
private IDQControlWfDefTypeService controlWfDefTypeService;

@Before
public void setUp() throws Exception {
    dqExec = new DqExec();
    dqCntlWfDefn = new DqCntlWfDefn();
    dqUtility = new DQUtility();
    dqCntlWfDefnTyp = new DqCntlWfDefnTyp();
    dqCntlWfDefnTyp.setDqCntlWfDefnTypCd("MIN_INCLUSIVE_VAL");
    dqExecWorkflowServiceImpl
            .setControlWfDefTypeService(controlWfDefTypeService);

}

@Test
public void testExecuteWorkflow() {
    when(controlWfDefTypeService.getDqCntlWfDefnTypCd(dqCntlWfDefn))
            .thenReturn(dqCntlWfDefnTyp);
    dqExecWorkflowServiceImpl.executeWorkflow(dqExec, dqCntlWfDefn);
}

}

Java class

@Override
public DqCntlWfExec executeWorkflow(final DqExec dqExec,
        final DqCntlWfDefn dqCntlWfDefn) {
final DqCntlWfExec dqCntlWfExec = new DqCntlWfExec();
dqCntlWfExec.setDqCntlWfExecEffDt(dqUtil.getDefaultEffectiveDt());
dqCntlWfExec.setDqCntlWfExecExpDt(dqUtil.getDefaultExpiryDt());
dqCntlWfExec.setDqCntlWfDefn(dqCntlWfDefn);
dqCntlWfExec.setDqExec(dqExec);

final DqCntlWfDefnTyp dqCntlWfDefnTyp = controlWfDefTypeService
    .getDqCntlWfDefnTypCd(dqCntlWfDefn);
     String workflowType = null;
if(null!=dqCntlWfDefnTyp){
    workflowType = dqCntlWfDefnTyp.getDqCntlWfDefnTypCd();
}

When ever i run the test file the when is not working and i am using mockito1.8.5 jar in the buildpath. The service call is being mocked but returns the null value.

final DqCntlWfDefnTyp dqCntlWfDefnTyp = controlWfDefTypeService
    .getDqCntlWfDefnTypCd(dqCntlWfDefn);

This object dqCntlWfDefnTyp is null

I have done this before and there was no problem with the when, It seems to be working with files i have done before. I had followed the same procedure for the test file but i couldnt figure out the issue. Can anyone please assist me

Thanks to all the folks in advance

like image 971
Gopi Avatar asked Dec 11 '13 11:12

Gopi


People also ask

What does when do in Mockito?

Mockito when() method It enables stubbing methods. It should be used when we want to mock to return specific values when particular methods are called. In simple terms, "When the XYZ() method is called, then return ABC." It is mostly used when there is some condition to execute.

Do nothing when a method is called Mockito?

Mockito 's doNothing() is used when you want to test void methods because void methods do not return anything so there is no way you can verify using assert. These void methods may be anywhere, for example, in service class, in dao class, etc.

What is stubbing 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.

How do you call a real method in Mockito?

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


4 Answers

Mockito mock works when we mock the objects loosely.

Here is the change i have made to make it work:

when(controlWfDefTypeService.getDqCntlWfDefnTypCd(any(DqCntlWfDefn.class))     .thenReturn(dqCntlWfDefnTyp); 

Instead of passing the object of the Mock class, I passed the class with the Matcher any() and it works.

like image 85
Gopi Avatar answered Sep 17 '22 11:09

Gopi


TL;DR If some arguments in your test are null, be sure to mock the parameter call with isNull() instead of any(SomeClass.class).


Explanation

This might not be the answer that helps OP, but might be useful for someone else. In my case the setup was all good, however, some mocks returned the desired thenReturn(...) value and some didn't.

It's important to understand, that the method call you're trying to mock (i.e. the method in when(someMock.methodToMock)) has to match the actual call and not the signature only.

In my case, I mocked a method with a signature:

public void SomeValue method(String string, SomeParam param) 

The call however, in the test was something like:

method("some string during test", null); 

Now if you mock the call with:

when(MockedClass.method(anyString(), any(SomeParam.class)) 

Mockito will not match it even though the signature is correct. The problem is that Mockito is looking for a call of method() with the arguments String and SomeParam, whereas the actual call was with a String and null. What you have to do is:

when(MockedClass.method(anyString(), isNull()) 

Hint

Since there are many isNull() implementations in different frameworks, be sure to use this one org.mockito.ArgumentMatchers.isNull.

like image 33
Younes El Ouarti Avatar answered Sep 16 '22 11:09

Younes El Ouarti


I think I have found your issue, but not all the credit goes to me.

Since you are trying to mock 'dqCntlWfDefnTyp' in your test class and the object itself is being instantiated in the class that you are trying to test, you inevitably run into some issues. The primary problem is that the object cannot be mocked because it is being recreated in during the test.

There are a few options, but the best choice in my humble opinion is using PowerMockito. You will be able to replace the object within the class that is being tested with the one you mock.

An excellent example of this usage of PowerMockito from @raspacorp on this question:

public class MyClass {
void method1{
    MyObject obj1=new MyObject();
    obj1.method1();
}
}

And the test class...

@RunWith(PowerMockRunner.class)
@PrepareForTest(MyClass.class)
public class MyClassTest {
@Test
public void testMethod1() {      
    MyObject myObjectMock = mock(MyObject.class);
    when(myObjectMock.method1()).thenReturn(<whatever you want to return>);   
    PowerMockito.whenNew(MyObject.class).withNoArguments().thenReturn(myObjectMock);

    MyClass objectTested = new MyClass();
    objectTested.method1();

    ... // your assertions or verification here 
}
}
like image 36
Chad Van De Hey Avatar answered Sep 16 '22 11:09

Chad Van De Hey


I had the same problem. The solution for me was to put the Mockito.when(...).thenReturn(...); into the @Before-SetUp method.

like image 28
Lazar Zoltan Avatar answered Sep 17 '22 11:09

Lazar Zoltan