Answer the question
In order to leave comments, you need to log in
Why Mock gives incorrect data?
Hello, I have a test class
@RunWith(MockitoJUnitRunner.class)
@SpringBootTest
public class UserRepositoryImplTest {
private static final Logger log = LoggerFactory.getLogger(UserRepositoryImplTest.class);
@Mock
JdbcTemplate jdbcTemplate;
@Before
public void initMocks(){
MockitoAnnotations.initMocks(this);
}
@Test
public void findByNameTest() {
User user = setupUser();
String userName = user.getUserName();
UserRepository userRepository = new UserRepositoryImpl();
ReflectionTestUtils.setField(userRepository, "jdbcTemplate", jdbcTemplate);
Mockito.when(jdbcTemplate.queryForObject(
FIND_BY_NAME,
new ForUnitTestUserRowMapper(),
userName))
.thenReturn(user);
assertEquals(user, userRepository.findByName(userName));
}
}
16:23:10.048 [main] DEBUG org.springframework.test.util.ReflectionTestUtils - Setting field 'jdbcTemplate' of type [null] on target object [com[email protected]7d61eccf ] or target class [class com.trainig.spring.main.project.repository.user.UserRepositoryImpl] to value [jdbcTemplate]
16:23:10.101 [main] INFO com.trainig.spring.main.project.repository.user. UserRepositoryImpl - find by name : name
16:23:10.121 [main] INFO com.trainig.spring.main.project.repository.user.UserRepositoryImpl - Empty user
java.lang.NullPointerException
at com.trainig.spring.main.project. entity.User.equals(User.java:136)
com.training.spring.main.project.repository.user.UserRepositoryImplTest.findByNameTest(UserRepositoryImplTest.java:50)
...
[MockitoHint] UserRepositoryImplTest.findByNameTest (see javadoc for MockitoHint):
[MockitoHint] 1. Unused... -> at com.training.spring.main.project.repository.user.UserRepositoryImplTest.findByNameTest(UserRepositoryImplTest.java: 45)
[MockitoHint] ...args ok? -> at com.trainig.spring.main.project.repository.user.UserRepositoryImpl.findByName(UserRepositoryImpl.java:63)
public static User setupUser() {
User user = new User();
user.setUserId(ID);
user.setUserName(USER_NAME);
user.setUserPassword(PASSWORD);
user.setRoles(Collections.singleton(new Role(ID, USER_ROLE)));
return user;
}
@Override
public User findByName(String userName) {
logger.info("find by name : {}", userName);
User user = jdbcTemplate.queryForObject(
FIND_BY_NAME,
(rs, rowNum) -> new User(
rs.getLong("user_id"),
rs.getString("user_name"),
rs.getString("user_password"),
Collections.singleton(new Role(
rs.getLong("role_id"),
rs.getString("role_name")
))),
userName);
if (Objects.isNull(user)) {
logger.info("Empty user");
return new User();
} else {
return user;
}
}
public static final String FIND_BY_NAME = "select ut.user_id, ut.user_name, ut.user_password," +
" user_role.role_id, role_name from \n" +
"user_role inner join user_to_role\n" +
"on user_role.role_id = user_to_role.role_id \n" +
"inner join user_table as ut\n" +
"on ut.user_id = user_to_role.user_id\n" +
"where ut.user_name = ?";
.thenReturn(user)
if (Objects.isNull(user)) {
logger.info("Empty user");
return new User();
} else {
return user;
}
if (Objects.isNull(user)) {
logger.info("Empty user");
return ModelUtil.setupUser();
} else {
return user;
}
Mockito.when(jdbcTemplate.queryForObject(
FIND_BY_NAME,
new ForUnitTestUserRowMapper(),
userName))
<b> .thenReturn(user);</b>
Answer the question
In order to leave comments, you need to log in
1. The most important thing. There is no point in integration tests to mock the database. To do this, use better testcontainers (at worst h2, but this is a sure way to shoot yourself in the foot).
2.
ReflectionTestUtils.setField(userRepository, "jdbcTemplate", jdbcTemplate);
wtf? Is there really no other way? Mockito.when(jdbcTemplate.queryForObject(
eq(FIND_BY_NAME),
any(ForUnitTestUserRowMapper.class),
anyString())
.thenReturn(user);
Didn't find what you were looking for?
Ask your questionAsk a Question
731 491 924 answers to any question