Здравствуйте, у меня есть тест класс
@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));
}
}
Я делал его по следующему примеру:
Пример.
Но я получаю NPE при попытке сравнить то что возвращает мок и подготовленный результат.
Вот стектрейс ошибки и логи до нее
16:23:10.048 [main] DEBUG org.springframework.test.util.ReflectionTestUtils - Setting field 'jdbcTemplate' of type [null] on target object [com.trainig.spring.main.project.repository.user.UserRepositoryImpl@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)
Тоесть если в классе
UserRepositoryImpl
поменять с
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>
?