Search code examples
javajunitmockingmockitopowermock

Mock a constructor with parameter


I have a class as below:

public class A {
    public A(String test) {
        bla bla bla
    }

    public String check() {
        bla bla bla
    }
}

The logic in the constructor A(String test) and check() are the things I am trying to mock. I want any calls like: new A($$$any string$$$).check() returns a dummy string "test".

I tried:

 A a = mock(A.class); 
 when(a.check()).thenReturn("test");

 String test = a.check(); // to this point, everything works. test shows as "tests"

 whenNew(A.class).withArguments(Matchers.anyString()).thenReturn(rk);
 // also tried:
 //whenNew(A.class).withParameterTypes(String.class).withArguments(Matchers.anyString()).thenReturn(rk);

 new A("random string").check();  // this doesn't work

But it doesn't seem to be working. new A($$$any string$$$).check() is still going through the constructor logic instead of fetch the mocked object of A.


Solution

  • The code you posted works for me with the latest version of Mockito and Powermockito. Maybe you haven't prepared A? Try this:

    A.java

    public class A {
         private final String test;
    
        public A(String test) {
            this.test = test;
        }
    
        public String check() {
            return "checked " + this.test;
        }
    }
    

    MockA.java

    import static org.hamcrest.MatcherAssert.assertThat;
    import static org.hamcrest.Matchers.equalTo;
    import static org.mockito.Mockito.mock;
    import static org.mockito.Mockito.when;
    
    import org.junit.Test;
    import org.junit.runner.RunWith;
    import org.mockito.Mockito;
    import org.powermock.api.mockito.PowerMockito;
    import org.powermock.core.classloader.annotations.PrepareForTest;
    import org.powermock.modules.junit4.PowerMockRunner;
    
    @RunWith(PowerMockRunner.class)
    @PrepareForTest(A.class)
    public class MockA {
        @Test
        public void test_not_mocked() throws Throwable {
            assertThat(new A("random string").check(), equalTo("checked random string"));
        }
        @Test
        public void test_mocked() throws Throwable {
             A a = mock(A.class); 
             when(a.check()).thenReturn("test");
             PowerMockito.whenNew(A.class).withArguments(Mockito.anyString()).thenReturn(a);
             assertThat(new A("random string").check(), equalTo("test"));
        }
    }
    

    Both tests should pass with mockito 1.9.0, powermockito 1.4.12 and junit 4.8.2