aime
aime

Reputation: 247

Spring Boot / Spring Data integration tests

Didn't manage to configure Spring Boot for integration testing. Cold you please take a look at the code below:

Entities

@Entity(name = "Item")
@Table(name = "item")
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
@Getter @Setter @NoArgsConstructor
public class Item extends CoreEntity {

    @Embedded
    protected CurrencyAmount amount;

    @Column(name = "operation_time")
    protected ZonedDateTime operationTime;

    @Column(name = "description")
    protected String description;

    @ManyToOne(cascade = CascadeType.ALL)
    @JoinColumn(name = "category_id")
    protected ItemCategory category;

}



@Entity(name = "Income")
@Table(name = "income")
@Getter @Setter @NoArgsConstructor
public class Income extends Item {

    @ManyToOne(cascade = CascadeType.ALL)
    @JoinColumn(name = "budget_id")
    private Budget budget;

    ...

}

Repository

@Repository("incomeDao")
public interface IncomeDao extends JpaRepository<Income, Long> {
}

Test configuration

@Configuration
@EnableJpaRepositories(basePackages = "dao.item")
@EntityScan(basePackages = {"model"})
@PropertySource("classpath:application.properties")
@EnableTransactionManagement
public class DaoTestConfiguration {

    @Autowired
    private Environment environment;

    public DataSource getDataSource() {
        DriverManagerDataSource dataSource = new DriverManagerDataSource();
        dataSource.setDriverClassName(environment.getProperty("spring.datasource.driver-class-name"));
        dataSource.setUrl(environment.getProperty("spring.datasource.url"));
        dataSource.setUsername(environment.getProperty("spring.datasource.username"));
        dataSource.setPassword(environment.getProperty("spring.datasource.password"));
        return dataSource;
    }

}

Application properties

spring.datasource.driver-class-name=org.h2.Driver
spring.datasource.url=jdbc:h2:mem:db;DB_CLOSE_DELAY=-1
spring.datasource.username=sa
spring.datasource.password=sa

Test case

@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes = DaoTestConfiguration.class)
@DataJpaTest
public class IncomeDaoTest {

    @Autowired
    private IncomeDao incomeDao;

    @Test
    public void testSave() {
        Budget budget = Budget.getBulider().setMonth(Month.NOVEMBER).build();
        ItemCategory category = ItemCategory.getBuilder()
                .setItemGroup(ItemGroup.INCOME)
                .setCathegoryName("Salary")
                .build();
        Income income = Income.getBuilder()
                .setBudget(budget)
                .setCurrencyAmount(new CurrencyAmount(Currency.getInstance("USD"), BigDecimal.TEN))
                .setDescription("Monthly salary")
                .setItemCategory(category)
                .setOperationTime(ZonedDateTime.of(2017, 1, 12, 12, 0, 0, 0, ZoneId.of("UTC")))
                .build();
        incomeDao.save(income);

        assertThat(incomeDao.findAll()).containsExactly(income);
    }
}

I tried a different configuration (its last edition), but all the time I get the same exception:

Caused by: org.h2.jdbc.JdbcSQLException: Таблица "INCOME" не найдена
Table "INCOME" not found; SQL statement:
insert into income (model/amount, currency, category_id, description, operation_time, budget_id, id) values (?, ?, ?, ?, ?, ?, ?) [42102-196]

More over the nature of the exception is strange as the main idea to let spring boot to auto-generate schema according to entity annotations. Thus, at the moment of insertion spring had to create table but looks that it didn't. If someone give an idea what I did wrong or if somebody already faced such an issue - please let me knkow. Thanks.

Upvotes: 0

Views: 1991

Answers (3)

Mideel
Mideel

Reputation: 829

If you want to do a @DataJpaTest, my answer is similar to Bhusan Umiyal, but use create instead of update.

spring.jpa.hibernate.ddl-auto=create

And like everyone else in here has said, don't use it along with @SpringBootTest.

Also make sure that your test classes are in the same or sub package with the main Spring Boot application class.

Upvotes: 0

Bhushan Uniyal
Bhushan Uniyal

Reputation: 5703

add this property in application.properties

spring.jpa.hibernate.ddl-auto=update

Upvotes: 1

davidxxx
davidxxx

Reputation: 131496

Either use @SpringBootTest (full loaded context) or use @DataJpaTest (JPA context).

From the documentation :

Annotation that can be used in combination with @RunWith(SpringRunner.class) for a typical JPA test. Can be used when a test focuses only on JPA components.

...

If you are looking to load your full application configuration, but use an embedded database, you should consider @SpringBootTest combined with @AutoConfigureTestDatabase rather than this annotation.

Besides, by specifying DaoTestConfiguration as configuration class in your test class :

@SpringBootTest(classes = DaoTestConfiguration.class)

you don't rely on default values for embedded database provided Spring boot as in DaoTestConfiguration , you declared the bean :

public DataSource getDataSource() {
    DriverManagerDataSource dataSource = new DriverManagerDataSource();
    dataSource.setDriverClassName(environment.getProperty("spring.datasource.driver-class-name"));
    dataSource.setUrl(environment.getProperty("spring.datasource.url"));
    dataSource.setUsername(environment.getProperty("spring.datasource.username"));
    dataSource.setPassword(environment.getProperty("spring.datasource.password"));
    return dataSource;
}

Either don't create this datasource and let Spring Boot do the job to create it or else specify also the property spring.jpa.hibernate.ddl-auto in the datasource bean declaration.

Upvotes: 1

Related Questions