Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Mockito: how to test that a constructor was called?

Tags:

I am using Mockito to test methods within my Java application.

How can I test that a constructor was called once?

I am trying to do a verification similar to this:

verify(myClass, times(1)).doSomething(anotherObject);

But I can't verify that the constructor was called as it doesn't have a method similar to e.g. doSomething().

like image 924
java123999 Avatar asked Aug 09 '16 09:08

java123999


People also ask

How do you check if a constructor is called?

Use the instanceof property. If the current instance is the instance of function then this is a constructor call. Else, this is a general function call.

How do you verify a method is called once Mockito?

Mockito verify() simple example It's the same as calling with times(1) argument with verify method. verify(mockList, times(1)). size(); If we want to make sure a method is called but we don't care about the argument, then we can use ArgumentMatchers with verify method.

Does Mockito mock call constructor?

0, we can now mock Java constructors with Mockito. This allows us to return a mock from every object construction for testing purposes. Similar to mocking static method calls with Mockito, we can define the scope of when to return a mock from a Java constructor for a particular Java class.

How do you mock a constructor method?

if your constructor is calling a method of its own class, you can fake the call using this API: // Create a mock for class MyClass (Foo is the method called in the constructor) Mock mock = MockManager. Mock<MyClass>(Constructor. NotMocked); // Faking the call to Foo mock.


2 Answers

You can do it with Mockito and PowerMockito.

Say you have ClassUnderTest with a constructor

public class ClassUnderTest {
    String name;
    boolean condition;

    public ClassUnderTest(String name, boolean condition) {
       this.name = name;
       this.condition = condition;
       init();
    }

    ...
}

And another class that calls that constructor

public class MyClass {

    public MyClass() { } 

    public void createCUTInstance() {
       // ...
       ClassUnderTest cut = new ClassUnderTest("abc", true);
       // ...
    }

    ...
}

At the Test class we could...

(1) use PowerMockRunner and cite both target classes above in the PrepareForTest annotation:

@RunWith(PowerMockRunner.class)
@PrepareForTest({ ClassUnderTest.class, MyClass.class })
public class TestClass {

(2) intercept the constructor to return a mock object:

@Before
public void setup() {
    ClassUnderTest cutMock = Mockito.mock(ClassUnderTest.class);
    PowerMockito.whenNew(ClassUnderTest.class)
                .withArguments(Matchers.anyString(), Matchers.anyBoolean())
                .thenReturn(cutMock);
}

(3) validate the constructor call:

@Test
public void testMethod() {
    // prepare
    MyClasss myClass = new MyClass();

    // execute
    myClass.createCUTInstance();

    // checks if the constructor has been called once and with the expected argument values:
    String name = "abc";
    String condition = true;
    PowerMockito.verifyNew(ClassUnderTest.class).withArguments(name, condition);
}
like image 165
Jose Tepedino Avatar answered Sep 17 '22 11:09

Jose Tepedino


This can't be done with Mockito, since the object being created is not a mocked object. This also means that you won't be able to verify anything on that new object either.

I've worked around this scenario in the past by using a Factory to create the object rather than newing it up. You're then able to mock the Factory to return the object required for your test.

Whether you're happy changing your design to suit your tests is up to you!

like image 21
StuPointerException Avatar answered Sep 19 '22 11:09

StuPointerException