I have the following class:
import name.package.OtherClass;
import name.package.Context;
import name.package.Configuration.keys;
public class MyClass{
public static void configure(Context context){
Configuration config = new OtherClass().getConfiguration(keys);
context.configure(config);
}
}
I want to mock the method OtherClass.getConfiguration()
. Could I do the following?
import org.mockito.Mock;
import org.mockito.Mockito;
public class MyClassTest{
@Mock
private Context context = Mockito.mock(Context.class);
@Mock
private OtherClass otherClass = Mockito.mock(OtherClass.class);
@Mock
private Context configurationMock = Mockito.mock(Configuration.class);
@Test
public void testConfigure(){
Mockito.when(otherClass.getConfiguration(keys)).thenReturn(configurationMock);
MyClass.configure(context);
verify(context.configure(configurationMock), times(1))
}
}
Remember that OtherClass
is not an argument of MyClass
, and I want to know if a mock of it inside the class of tests takes effect in MyClass
instance when I run the test.
I have tried executing this but didn't get clear results.
CodePudding user response:
Could I do the following?
Yes you can do it but you are doing it the wrong way. As your method OtherClass.getConfiguration(keys)
is a static method, you will have to write it by following this exemple.
As your method is not static anymore, your code will look like this:
import org.mockito.Mock;
import org.mockito.Mockito;
@ExtendWith(MockitoExtension.class)
public class MyClassTest {
@Mock
private Context context;
@Mock
private OtherClass otherClass;
@InjectMocks
private MyClass myClass;
@Test
public void testConfigure(){
Mockito.when(otherClass.getConfiguration(any(Key.class))).thenReturn(new Configuration());
MyClass.configure(context);
verify(context.configure(configurationMock), times(1))
}
}
then I want to know if a mock of it inside the class of tests takes effect in MyClass instance when I run the test
Yes your mock takes effect in your class, as it is the purpose of the mock to give you the ability to modify the behaviour of your dependencies.
Also, when using the @Mock
annotation, you don't need to create a new instance and your did not define a class undertest
with @InjectMocks
.
While calling the when
method, you will declare the class type of keys
with any(Key.class)
parameter and you will provide a new instance of configuration.
CodePudding user response:
Modern versions of Mockito allow you to mock constructors.
First, make sure you have the mockito-inline
dependency instead of the mockito-core
dependency. E.g., in Maven, you'll have something like this:
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-inline</artifactId>
<version>4.10.0</version>
<scope>test</scope>
</dependency>
Then, you can use the mockConstruction
method to replace the constructor of OtherClass
, and mock what even behavior you need for it:
class MyClassTest {
@Mock
Configuration mockedConfig;
@Mock
Context mockedContext;
@Test
public void testConfigure() {
try (MockedConstruction<OtherClass> mockedConstruction =
Mockito.mockConstruction(OtherClass.class, (mock, context) -> {
Mockito.when(mock.getConfiguration(Mockito.any())).thenReturn(mockedConfig);
// Additional mocking you may need
})) {
MyClass.configure(mockedContext);
// assertions...
}
}
}