简体   繁体   中英

How test JdbcTemplate methods using jUnit?

I wrote simple java project using Spring and JdbcTemplate. I wrote SpringConfig class where I put my Postgres database info and create DataSource and JdbcTemplate beans. Then I wrote CRUD methods with Autowired class constructor, and everything is running perfect but tests not. I want to use H2 database and create application.properties in test.resources package, then I create test class where I create class constructor and also Autowire it, and when am trying to test CRUD methods I get ParameterResolutionException: "failed to resolve parameter [javax.sql.DataSource arg0] in constructor". Could you please show my mistake:

@Configuration
public class SpringConfig {

private static final String URL = "jdbc:postgresql://localhost:5432/test";
private static final String DRIVER = "org.postgresql.Driver";
private static final String USERNAME = "root";
private static final String PASSWORD = "123";

@Bean
public DataSource dataSource() {

    DriverManagerDataSource dataSource = new DriverManagerDataSource();
    dataSource.setDriverClassName(DRIVER);
    dataSource.setUrl(URL);
    dataSource.setUsername(USERNAME);
    dataSource.setPassword(PASSWORD);
    return dataSource;
}
@Bean
public JdbcTemplate jdbcTemplate(){
    return new JdbcTemplate(dataSource());
}
@Repository
public interface SimpleDao<E> {

void create(E e);

Optional<E> read(int id);

void delete(E e);

void update(E e);

List<E> index();
}
public interface StudentDao extends SimpleDao<Student> {
}
@Component
public class SpringStudentDao implements StudentDao {
private static Logger logger = LoggerFactory.getLogger(SpringStudentDao.class);

private final JdbcTemplate jdbcTemplate;

public SpringStudentDao(JdbcTemplate jdbcTemplate) {
    this.jdbcTemplate = jdbcTemplate;
}

@Override
public void create(Student student) {
    String sql = "INSERT INTO student VALUES(?,?,?)";
    int insert = jdbcTemplate.update(sql, student.getID(), student.getName(), student.getSurname());
    if (insert == 1) {
        logger.info("New student added " + student.toString());
    }
}

@Override
public Optional<Student> read(int id) {
    String sql = "SELECT * FROM student WHERE id=?";
    Student student = null;
    try {
        student = jdbcTemplate.queryForObject(sql, new Object[]{id}, new StudentMapper());
    } catch (DataAccessException exception) {
        logger.info("Student not found " + id);
    }
    return Optional.ofNullable(student);
}

@Override
public List<Student> index() {
    String sql = "SELECT * FROM student";
    return jdbcTemplate.query(sql, new StudentMapper());
}
@DataJdbcTest
class SpringStudentDaoTest {

private JdbcTemplate jdbcTemplate;
private SpringStudentDao studentDao;


@Autowired
public SpringStudentDaoTest(DataSource dataSource){
    jdbcTemplate = new JdbcTemplate(dataSource);
    studentDao = new SpringStudentDao(jdbcTemplate);

}

@Test
public void shouldGetListOfStudents(){
    List<Student> students = studentDao.index();
    assertEquals(4, students.size());
}

Why do you try to build the JdbcTemplate for your embedded db instead of auto-configuring it?

@DataJdbcTest
public class JdbcTest {

    JdbcTemplate jdbcTemplate;

    @Autowired
    JdbcTest(JdbcTemplate jdbcTemplate) {
        this.jdbcTemplate = jdbcTemplate;
    }

    @Test
    public void myTest() {
    }

}

Check info on @DataJdbcTest at Auto-configured Data JDBC Tests

By default, it configures an in-memory embedded database, a JdbcTemplate, and Spring Data JDBC repositories. Regular @Component beans are not loaded into the ApplicationContext.

Full list of components auto-configured by @DataJdbcTest - See Appendix D. Test auto-configuration annotations

org.springframework.boot.autoconfigure.cache.CacheAutoConfiguration org.springframework.boot.autoconfigure.data.jdbc.JdbcRepositoriesAutoConfiguration org.springframework.boot.autoconfigure.flyway.FlywayAutoConfiguration org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration org.springframework.boot.autoconfigure.jdbc.DataSourceTransactionManagerAutoConfiguration org.springframework.boot.autoconfigure.jdbc.JdbcTemplateAutoConfiguration org.springframework.boot.autoconfigure.liquibase.LiquibaseAutoConfiguration org.springframework.boot.autoconfigure.transaction.TransactionAutoConfiguration org.springframework.boot.test.autoconfigure.jdbc.TestDatabaseAutoConfiguration

Why your approach failed:

If you're familiar with the Spring Test Framework, you may be used to using @ContextConfiguration(classes=…) in order to specify which Spring @Configuration to load. Alternatively, you might have often used nested @Configuration classes within your test.

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM