Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Mockito Spy Test

I am using Mockito to write tests for code. However I am stuck at following scenario - Class A has 2 methods, method1() and method2(). I tried using ArgumentCaptor to catch values sent to method2(). But, since I am using @Spy, I cannot use Matchers.

How do I test method1()?

class A{
    B b;
    method1(arg1, arg2){
       //some logic
       method2(arg1, arg2, ....argN);
    }

   method2(arg1, arg2,....argN){
       //some logic
       b.method3(arg1, arg2...);
   }
}

How to verify method2 receives same argument values? Following is the test class I wrote:

Class TestA{

@Mock
B b;

@Spy
@InjectMocks   //required else b is null
A a = new A();

@Test
public void testMethod1(){

 a.method1(arg1, arg2);

  //How to verify method2 receives same argument values (arg1, arg2)????
  //verify(a, times(1)).method2(.......);   
}

}

like image 628
aces. Avatar asked Apr 23 '12 20:04

aces.


2 Answers

I was intrigued by this post and the comments left by @David so I decided to code a working example for those who follow like me

/*
 * class to test
 */
public class A {

    public void methodA(String str) {
        this.methodB(str);
    }

    protected void methodB(String str) {
        // some implementation
    }
}

We want to assert that the value being passed into methodB() is what we expect. Reading up on the ArgumentCaptor led me to discover the equivalent Captor Annotation

import static org.junit.Assert.assertEquals;
import static org.mockito.Mockito.verify;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import org.mockito.Captor;
import org.mockito.Spy;
import org.mockito.runners.MockitoJUnitRunner;

@RunWith(MockitoJUnitRunner.class)
public class MultipleMethodCallTest {

    @Spy
    A a = new A();

    @Captor ArgumentCaptor<String> captor;

    @Test
    public void captureSecondMethodCallArgument() throws Exception {

        // EXPECTED

        String greeting = "hello world";

        // PERFORM TEST

        a.methodA(greeting);

        // ASSERT

        verify(a).methodB(captor.capture());

        assertEquals(greeting, captor.getValue());
    }
}

This example was tested with

  • mockito-all-1.8.5.jar
  • junit-4.8.2.jar
like image 73
Brad Avatar answered Sep 22 '22 09:09

Brad


You cant, you have to verify it by B's method3 call. If your args to method2 have no effect on method3, theses args could be useless at all?!

like image 40
Omnaest Avatar answered Sep 24 '22 09:09

Omnaest