spring boot测试在所有测试前执行一次sql脚本

问题描述 投票:0回答:1

我想为课堂上的所有测试填充一次数据库。

@ToString
@Builder
@NoArgsConstructor
@AllArgsConstructor
@Entity
public class Location {
    public static final Location UNKNOWN = new Location();

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    private String name;
    @Column(unique = true, nullable = false, updatable = false)
    private String code;

    public boolean sameIdentityAs(Location other) {
        return this.code.equals(other.code);
    }
}

import_locations.sql(短版目录)

INSERT INTO LOCATION (name, code)
    VALUES
          ('Sydney', 'SYD'),
          ('Seoul', 'SEL'),
          ('Tokyo', 'TYO'),
          ('Hong Kong', 'HKG');
@Sql({"/db/import_locations.sql"})
@SpringBootTest
class CargoTest {

    @Autowired
    LocationRepository locationRepository;
    @Autowired
    CargoRepository cargoRepository;

    @Test
    void testConstruction() {
        LocalDate arrivalDeadline = LocalDate.of(2024, Month.JUNE, 1 );
        RouteSpecification routeSpecification = RouteSpecification.builder()
               .arrivalDeadline(arrivalDeadline)
               .origin(locationRepository.findByCode("KYI"))
               .destination(locationRepository.findByCode("SYD")).build();

        Cargo cargo = new Cargo("TRACK-001", routeSpecification);
        cargoRepository.save(cargo);

        assertEquals("TRACK-001", cargoRepository.findByTrackingId("TRACK-001").getTrackingId());
        assertEquals(RoutingStatus.NOT_ROUTED, cargo.getDelivery().getRoutingStatus());
        assertEquals(TransportStatus.NOT_RECEIVED, cargo.getDelivery().getTransportStatus());
        assertEquals(Location.UNKNOWN, cargo.getDelivery().getLastKnownLocation());
//        assertEquals(Voyage.NONE, cargo.getDelivery().getCurrentVoyage());
    }

    @Test
     void testLastKnownLocationUnknownWhenNoEvents() {
        LocalDate arrivalDeadline = LocalDate.of(2024, Month.JUNE, 1 );
        RouteSpecification routeSpecification = RouteSpecification.builder()
                .arrivalDeadline(arrivalDeadline)
                .origin(locationRepository.findByCode("KYI"))
                .destination(locationRepository.findByCode("SYD")).build();

        Cargo cargo = new Cargo("TRACK-002", routeSpecification);
        cargoRepository.save(cargo);
        assertEquals(Location.UNKNOWN, cargo.getDelivery().getLastKnownLocation());
    }
}

应用程序.yml

spring:
  datasource:
    url: jdbc:h2:file:./h2data/demodb
    driverClassName: org.h2.Driver
    username: sa
    password: password
  jpa:
    database-platform: org.hibernate.dialect.H2Dialect
    hibernate:
      ddl-auto: create
    show-sql: true
    properties:
      hibernate:
        format_sql: true
  h2:
    console:
      enabled: true

我的问题是如何执行一次 import_locations.sql 文件,因为它是静态数据,不会为所有测试更改。 目前它为每个测试运行它,据我所知这是@sql on class 的默认行为。我应该在@BeforeAll 方法上开发一些自定义执行程序吗? 填充数据库的现代解决方案是什么?

spring junit spring-test spring-boot-test
1个回答
0
投票

SpringBootTest
-esque 这样做的方式,承认
@Sql
注释有两个指令,beforeafter
@Test
's,将是另一个 sql 脚本来撤消你的另一个,如果你只是打算对于在两者之前执行的同一个 - 即添加到类注释中; (来自文档,类似

@Sql(
    scripts = "delete-test-data.sql",
    executionPhase = AFTER_TEST_METHOD
)

或者,因为您可以让多个脚本运行相同的

@Sql
指令,所以您可以;

@Sql({"/locations_schema.sql", "/import_locations.sql"})

如果您能够用运行

@Entity
命令的“locations_schema.sql”文件中的模式定义替换您的
public class Location
CREATE OR REPLACE TABLE LOCATION (...)

© www.soinside.com 2019 - 2024. All rights reserved.