Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How does mockito create an instance of the mock object

When i create a mock object of say class Employee. It doesnt call the constructor of Employee object. I know internally Mockito uses CGLIb and reflection, creates a proxy class that extends the class to mock. If it doesnt call the constructor of employee how is the mock instance of employee class created ?

like image 390
Cshah Avatar asked Jun 29 '10 05:06

Cshah


People also ask

How do you make a mock object in JUnit?

Creating mock objects with the Mockito API class) extension for JUnit 5 in combination with the @Mock annotation on fields. Using the static mock() method. Using the @Mock annotation.

Is Mockito mock same as @mock?

Mockito offers two equivalent ways of mocking: Using static methods and. Using @Mock annotations.


2 Answers

Mockito uses CGLib to generate class object. However to instantiate this class object it uses Objenesis http://objenesis.org/tutorial.html

Objenesis is able to instantiate object without constructor using various techniques (i.e. calling ObjectStream.readObject and similar).

like image 56
Tibor Blenessy Avatar answered Nov 02 '22 05:11

Tibor Blenessy


Mockito is using reflection and CGLib to extend the Employee class with a dynamically created superclass. As part of this, it starts by making all the constructors of Employee public - including the default constructor, which is still around but private if you declared a constructor which takes parameters.

public <T> T imposterise(final MethodInterceptor interceptor, Class<T> mockedType, Class<?>... ancillaryTypes) {
    try {
        setConstructorsAccessible(mockedType, true);
        Class<?> proxyClass = createProxyClass(mockedType, ancillaryTypes);
        return mockedType.cast(createProxy(proxyClass, interceptor));
    } finally {
        setConstructorsAccessible(mockedType, false);
    }
}

private void setConstructorsAccessible(Class<?> mockedType, boolean accessible) {
    for (Constructor<?> constructor : mockedType.getDeclaredConstructors()) {
        constructor.setAccessible(accessible);
    }
}

I presume that it calls the default constructor when the superclass is created, though I haven't tested that. You could test it yourself by declaring the private default constructor Employee() and putting some logging in it.

like image 3
Lunivore Avatar answered Nov 02 '22 04:11

Lunivore