How to do partial migration in Flyway for testing?

Viewed 413

I am trying to write a test to validate whether my new migration script (located in src/main/resources/db/migration) executes correctly on the existing data in my Postgres DB.

I have 5 migration scripts where the 2nd one creates the initial Users table with some columns and the 5th one adds onto that existing Users table with a new column and default values for that new column.

First, I would like to only migrate up to the script, so that the initial version of Users table, then I will populate it normally, and finally, complete the migration by running the 5th script, and then check if the 5th script actually updated the existing data or not. However, I do not understand exactly how I can just migrate only to some version, and then later on migrate to the remaining versions...

Here is what I have so far:

Actual Test

@RunWith(SpringRunner.class)
@SpringBootTest
class MigrationTest extends ComponentTest {

  private static final String USER_ID = "1337";

  @Autowired
  private InitialUserRepository initialUserRepository;
  @Autowired
  private UserRepository userRepository;

  @Autowired
  private Flyway flyway;

  @Transactional
  @Test
  public void test() {

    flyway.baseline(); // default 1
    flyway.migrate(); // this will migrate to the final script/version where it will add the new column
    // replace the above line, flyway.migrate(), with a partial migration to version 2 ONLY, something like flyway.migrate(2)

    var initialUserMappingEntity = new InitialUserMappingEntity(USER_ID, "some other data");
    initialUserRepository.saveAndFlush(initialUserMappingEntity);

    var user = initialUserRepository.findById(USER_ID);
    assertTrue(user.isPresent());

    // complete the full migration here, something like flyway.migrate(5)

    var updatedUser = userRepository.findById(USER_ID);
    assertTrue(updatedUser.isPresent());
    assertNotNull(updatedUser.get().getNewColumn());
  }
}

EmptyMigrationStrategyConfig

@Configuration
public class EmptyMigrationStrategyConfig {

  @Bean
  public FlywayMigrationStrategy flywayMigrationStrategy() {
    return flyway -> {
      // do nothing
    };
  }
}

application-test.yaml

spring:
  flyway:
    locations: classpath:/db/migration
2 Answers

In the end I replaced the

var initialUserMappingEntity = new InitialUserMappingEntity(USER_ID, "some other data");
initialUserRepository.saveAndFlush(initialUserMappingEntity);

with an insertion script located in: /db/testdata/V2.1__insert_user_data.sql and then just did one migration until the end.

So you basically need to add an insertion script that comes before the final script that you want to test in your /db/migration and then modify your spring.flyway.locations to have these two base path

Related