Home > Software design >  Test Dao layer with queries stored in properties file
Test Dao layer with queries stored in properties file

Time:12-22

I'm developing REST App for the IT courses. One of the requirements was to use Spring-JDBC with all queries to be stored in separate properties file. Here is a part of my UserDaoImpl:

@Repository
@RequiredArgsConstructor
@PropertySource(value = "classpath:/user_queries.properties")
@Log
public class UserDaoImpl implements UserDao {
    
    private final NamedParameterJdbcTemplate template;
    private final RowMapper<User> rowMapper;
    
    @Value("${find.by_id}")
    private String findById;

    @Override
    public Optional<User> findById(int id) {
        SqlParameterSource param = new MapSqlParameterSource("id", id);
        User user = null;
        try {
            user = template.queryForObject(findById, param, BeanPropertyRowMapper.newInstance(User.class));
        } catch (DataAccessException ex) {
            String.format("User with id - %d, not found.", id);
        }
        return Optional.ofNullable(user);
    }
    
}

All method work fine, but troubles started when I wrote my Test to this class:

@RunWith(SpringRunner.class)
@SpringBootTest(classes = {TestDBConfiguration.class})
public class UserDaoTest {
    
    @Autowired
    DataSource dataSource;
    
    @Test
    public void findByIdTest() {
        NamedParameterJdbcTemplate template = new NamedParameterJdbcTemplate(dataSource);
        UserRowMapper userMapper = new UserRowMapper();
        UserDao userDao = new UserDaoImpl(template, userMapper);
        User user = new User(1, "John", "Doe",
                "$2a$04$MzVXtd4o0y4DOlyHMMLMDeE4/eezrsT5Xad.2lmGr/NkCpwBgvn3e",
                "[email protected]", true);
        assertEquals(Optional.of(user), userDao.findById(1));
    }

}

When I run this Test my findById is always null. Is there any way to run this test and keep all queries inside the separate file?

CodePudding user response:

Since your UserDaoImpl uses Spring annotations (@Value, @PropertySource, etc), you have to initialize it via Spring to enable their injection. Or else you'd have to supply all these values yourself manually.

So in your test you should inject the DAO itself:

@Autowired
private UserDao userDao;

Or if you want to go manual way (not recommended), allow setting field findById via constructor (recommended) same way you're passing template, userMapper.

CodePudding user response:

You could use this annotation to force the load of your properties:

@TestPropertySource(properties = { "classpath:/user_queries.properties" })
public class UserDaoTest
//logic
}

If this don't works, add a copy of your user_queries.properties to the src/test/resources folder.

  • Related