Hot questions for Using Mockito in testcase

Hot questions for Using Mockito in testcase

Question:

Trying to use mockito in my AndroidTestCase. I added the dependencies to the build.gradle:

final DEXMAKER_VERSION = '1.2'

dependencies {
    // ...
    androidTestCompile "com.google.dexmaker:dexmaker:${DEXMAKER_VERSION}"
    androidTestCompile "com.google.dexmaker:dexmaker-mockito:${DEXMAKER_VERSION}"
    androidTestCompile 'org.mockito:mockito-core:1.10.19'

}

The TestCase with the mockito initialization:

public class UsersListPresenterTest extends AndroidTestCase {

    public void setUp() throws Exception {
        MockitoAnnotations.initMocks(this);
    }

    public void testInitialize() throws Exception {

    }
}

But as soon as I add any attribute to the class, even before adding any annotation the test start to crash:

public class UsersListPresenterTest extends AndroidTestCase {

    String mockString;

    public void setUp() throws Exception {
        MockitoAnnotations.initMocks(this);
    }

    public void testInitialize() throws Exception {

    }
}

With the following stacktrace

java.lang.NullPointerException: Attempt to invoke virtual method 
    'java.lang.Class java.lang.Object.getClass()' on a null object reference
at com.google.dexmaker.mockito.DexmakerMockMaker.getInvocationHandlerAdapter(DexmakerMockMaker.java:80)
at com.google.dexmaker.mockito.DexmakerMockMaker.getHandler(DexmakerMockMaker.java:75)
at org.mockito.internal.util.MockUtil.isMockitoMock(MockUtil.java:74)
at org.mockito.internal.util.MockUtil.isMock(MockUtil.java:66)
at org.mockito.internal.configuration.injection.scanner.MockScanner.isMockOrSpy(MockScanner.java:86)
at org.mockito.internal.configuration.injection.scanner.MockScanner.preparedMock(MockScanner.java:72)
at org.mockito.internal.configuration.injection.scanner.MockScanner.scan(MockScanner.java:61)
at org.mockito.internal.configuration.injection.scanner.MockScanner.addPreparedMocks(MockScanner.java:47)
at org.mockito.internal.configuration.InjectingAnnotationEngine.injectMocks(InjectingAnnotationEngine.java:96)
at org.mockito.internal.configuration.InjectingAnnotationEngine.processInjectMocks(InjectingAnnotationEngine.java:62)
at org.mockito.internal.configuration.InjectingAnnotationEngine.process(InjectingAnnotationEngine.java:56)
at org.mockito.MockitoAnnotations.initMocks(MockitoAnnotations.java:108)
at com.myproject.presentation.UsersListPresenterTest.setUp(UsersListPresenterTest.java:28)
at android.test.AndroidTestRunner.runTest(AndroidTestRunner.java:191)
at android.test.AndroidTestRunner.runTest(AndroidTestRunner.java:176)
at android.test.InstrumentationTestRunner.onStart(InstrumentationTestRunner.java:555)
at android.app.Instrumentation$InstrumentationThread.run(Instrumentation.java:1853)

What am I doing wrong?


Answer:

You could try to replace

MockitoAnnotations.initMocks(this);

with this

System.setProperty("dexmaker.dexcache", getContext().getCacheDir().getPath());

It works for me. See ref here

Question:

I am writing test case for servlets using mockito.

In servlet response is set using servletoutputstream.

i send request the servlet is working properly also giving output in console but in testclass i am not getting class. below is the code for setting response :

protected void commitResponseBuffer(String buffer, ServletResponse response) throws IOException 
{
    response.setContentType("text/plain");
    System.out.println("Uncompressed Response Buffer : Size = " + buffer.length());
    // write to ZipOutputStream
    ByteArrayOutputStream bos = new ByteArrayOutputStream ();
    ZipOutputStream out = new ZipOutputStream(bos);
    out.putNextEntry(new ZipEntry("response.txt"));
    out.write(buffer.getBytes("UTF-8"));
    //out.flush();
    out.closeEntry();
    out.close ();
    bos.close();
    // encode to Base64 string
    String b64String = Base64.encodeBase64String(bos.toByteArray());
    // set the response
    ServletOutputStream servletOut = response.getOutputStream();
    response.setContentLength(b64String.length());
    System.out.println("Compressed Response Buffer : Size = " + b64String.length());
    servletOut.print(b64String);
    System.out.println(b64String);
    servletOut.close();
}

and in test class

    when(response.getOutputStream()).thenReturn(servletOut);
    new xlCollaborationService().service(request, response);        
    System.out.println("Response Buffer in mock :"+response.getContentType());

can anyone suggest me how to read the response in test class ??? Thanks in Advance.


Answer:

It seems you're on the right track.

You can use Mockito's ArgumentCaptor to capture arguments passed in to a mock and 'capture' the value. Documentation here

    ServletResponse response = mock(ServletResponse.class);
    ServletOutputStream servletOut = mock(ServletOutputStream.class);
    when(response.getOutputStream()).thenReturn(servletOut);

    new xlCollaborationService().service(request, response);

    // Capture argument
    ArgumentCaptor<String> bufferCaptor = ArgumentCaptor.forClass(String.class);
    verify(servletOut).print(bufferCaptor.capture());

    String responseBody = bufferCaptor.getValue();
    System.out.println(responseBody);

Question:

I am trying to test Kafka callback onFailure method:

     @Override
        public void onFailure(Throwable ex) {
        logger.error("Failure while sending message in kafka.", ex);
            }

My test case code using Mockito. I am setting exception in object of class SettableListenableFuture.



   SettableListenableFuture<SendResult<String, DeserializationResult<EnvelopeExpanded<SpecificRecord>>>> future2 = new SettableListenableFuture<>();
                future2.setException(new Exception("Could not publish to Kafka"));
    Exception ex = new Exception("Could not publish to Kafka");
    verify(logger, times(1)).error("Failure while sending message in kafka.", ex);

I am getting this error

  Argument(s) are different! Wanted:
    logger.error(
        "Failure while sending message in kafka.",
        java.lang.Exception: Could not publish to Kafka
    );

    Actual invocation has different arguments:
    logger.error(
        "Failure while sending message in kafka.",
        java.lang.Exception: Could not publish to Kafka
    );

Both wanted and actual arguments are same but it still throws error. Can anyone help me with this ??


Answer:

System.out.println(new Exception("Could not publish to Kafka").equals(new Exception("Could not publish to Kafka"))) will print false

so

   Exception ex = new Exception("Could not publish to Kafka");
   SettableListenableFuture<...> future2 = new SettableListenableFuture<>();
            future2.setException(ex);
   verify(logger, times(1)).error("Failure while sending message in kafka.", ex);

should work