Reputation: 4609
My user class is as follows,
public class UserResource {
@Inject UserService userService;
public boolean createUser(User user) {
DbResponse res = userService.addUser(user);
if(res.isSuccess){
return true;
}else{
return false;
}
}
}
My test class looks as follows,
public class UserResourceTest {
UserResource userResource;
@BeforeMethod
void beforeMethod() {
userResource = new UserResource();
}
@Test
public void test() {
User user= mock(User.class);
boolean res= userResource.createUser(user);
assert(res);
}
}
As you can see a UserService object should be injected into the UserResource class. How can I inject a mock UserService object to userResource object inside my test?
FYI:
Upvotes: 4
Views: 9121
Reputation: 15634
Although I completely support the answer of @Nkosi I'd like to add this for completeness:
Use Mockitos JUnitRule
to reate the mocks as described here: http://www.vogella.com/tutorials/Mockito/article.html :
public class UserResourceTest {
@Rule
public MockitoRule mockitoRule = MockitoJUnit.rule();
@Mock
private DbResponse mockResponse;
@Mock
private UserService mockService;
@Test
public void test() {
//Arrange
boolean expected = true;
when(mockResponse.isSuccess).thenReturn(expected);
when(mockService.addUser(user)).thenReturn(mockResponse);
// ...
Also then you could also use Mockitos @InjectMocks
annotation like this:
public class UserResourceTest {
@Rule
public MockitoRule mockitoRule = MockitoJUnit.rule();
@Mock
private DbResponse mockResponse;
@Mock
private UserService mockService;
@InjectMocks
private UserResource userResource; // do not instantiate in test method
// ...
But I personally would discourage from it.
Yes, it is more convenient since it determines by reflection which dependency injection method you use. But if you don't have a "seam" to inject a certain dependency (neither Costructor parameter, non final property nor setter of matching type) you don't get a compile error which I personally find problematic.
Upvotes: 2
Reputation: 247561
Consider using explicit dependency principal via constructor injection as it states very clearly what is required by the class in order to perform its particular function.
public class UserResource {
private UserService userService;
@Inject
public UserResource(UserService userService) {
this.userService = userService;
}
public boolean createUser(User user) {
DbResponse res = userService.addUser(user);
if(res.isSuccess){
return true;
}else{
return false;
}
}
}
and mock the UserService
as well and assign it to the subject under test. Configure the desired/mocked behavior for the test.
public class UserResourceTest {
@Test
public void test() {
//Arrange
boolean expected = true;
DbResponse mockResponse = mock(DbResponse.class);
when(mockResponse.isSuccess).thenReturn(expected);
User user = mock(User.class);
UserService mockService = mock(UserService.class);
when(mockService.addUser(user)).thenReturn(mockResponse);
UserResource userResource = new UserResource(mockService);
//Act
boolean actual = userResource.createUser(user);
//Assert
assert(expected == actual);
}
}
Upvotes: 6