I would like to mock the following class:
public class MyRunner {
private String name;
private User user;//not final
public MyRunner(String name, User user) {
this.name = name;
this.user = user
}
//...something complicated in the methods
}
Just like with JMockit
@ExtendWith(MockitoExtension.class)
public class MyRunnerTest {
@Inject
private String name = "sth";
@Inject
private User user;
@Tested
private MyRunner tested;
}
Similarly with Mockito 3,
@ExtendWith(MockitoExtension.class)
public class MyRunnerTest {
@Mock
private String name;
@Mock
private User user;
@InjectMocks
private MyRunner tested;
@Test //from JUnit5
public void testSth() {
//...
}
}
Problem : The injection of the name
string into the MyRunner
during construction would fail due to the fact that String
is a final class. Got error message like:
Cannot mock/spy class java.lang.String
Mockito cannot mock/spy because :
- final class
It is possible to intialize the tested class with new keyword:
@ExtendWith(MockitoExtension.class)
public class MyRunnerTest {
private String name = "sth";
@Mock
private User user;
private MyRunner tested = new MyRunner(name, user);
@Test //from JUnit5
public void testSth() {
//...
}
}
However, the solution above is not as fluent as merely using the annotation
Question : How to inject the final class into the object annotated with @InjectMocks
instead of constructing it with new
keyword explicitly?
There are many approaches to this. Here are 3 conceptually different ones:
Option 1
First off, if you're really talking about the String, than probably mocking it doesn't have much sense: Basically your example doesn't require mockito at all. You can simply:
public class UserTest {
private final String NAME = "sampleName;
private User tested = new User(NAME);
...
}
Option 2
Now, assuming that you're not really talking about String
class here, the best option is to program by Interfaces for which creating Mocks is fairly simple:
public class User {
public User(Name name) {
...
}
}
public interface Name {
String getValue();
}
@ExtendsWith(MockitoExtension.class)
public class UserTest
@Mock
private Name name;
@InjectMocks
private User tested;
Option 3
If you're absolutely required to mock static class, you can do that in mockito but it requires some additional setup: basically you create a file org.mockito.plugins.MockMaker
in the directory src/test/resources/mockito-extensions that will contain:
mock-maker-inline
See this tutorial for more information
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.