3

I need to integrate the cucumber with spring in a practice. But I can't import some test data with spring's @Sql annotation. However the other integration tests that not use cucumber works fine. I didn't find why? The cucumber runner:

@RunWith(Cucumber.class)
@CucumberOptions(features={"classpath:features/"})
public class CucumberIT {

}

And the step defination:

@RunWith(SpringRunner.class)
@ContextConfiguration(classes={DevDbConfig.class})
@Sql("classpath:test-reader-data.sql")
@Transactional
@ActiveProfiles("dev")
public class StepDefines {

  @Autowired
  ReaderService readerService;

  Reader reader;

  @Given("^a user with name Lily$")
  public void a_user_with_name_Lily() throws Throwable {
    reader = readerService.findByName("Lily"); // reader is null here!
  }

  @Given("^this user Lily exists$")
  public void this_user_Lily_exists() throws Throwable {
      assertThat(reader, notNullValue());
  }

  @Then("^Lily's info should be returned$")
  public void lily_s_info_should_be_returned() throws Throwable {
      assertThat(reader.getName(), is("Lily"));
  }

}

But the following testing code can import the testing data normally:

@RunWith(SpringRunner.class)
@ContextConfiguration(classes={DevDbConfig.class})
@Sql("classpath:test-reader-data.sql")
@Transactional
@ActiveProfiles("dev")
public class ReaderServiceTest {

  @Autowired
  ReaderService readerService;

  @Autowired
  EntityManager entityManager;

  @Test
  public void testQueryByIdAndShouldNotReturnNull() {    
    Reader reader = readerService.findByName("Lily");
    assertThat(reader, notNullValue()); // reader is not null!
  }

}

Thanks!

1 Answer 1

6

The @Sql will be executed by SqlScriptsTestExecutionListener. The Spring SpringJUnit4ClassRunner will register all of the TestExecutionListeners.

From theSqlScriptsTestExecutionListenerjava doc, it says:

Scripts and inlined statements will be executed before or after execution of the corresponding test method, depending on the configured value of the executionPhase flag.

So a class level @Sql is equivalent to all @Testmethods with individual @Sqlannotation.

However, when cucumber is running, it won't execute any @Test method and the @Sql doesn't have chance to be executed.

Finally, I have to do it myself:

  @Autowired
  DataSource ds;

  @Given("^a user with name Lily$")
  public void a_user_with_name_Lily() throws Throwable {
    ScriptUtils.executeSqlScript(ds.getConnection(), new ClassPathResource("test-reader-data.sql"));
    reader = readerService.findByName("Lily");
  }

  @Given("^this user Lily exists$")
  public void this_user_Lily_exists() throws Throwable {
    assertThat(reader, notNullValue());
  }

  @Then("^Lily's info should be returned$")
  public void lily_s_info_should_be_returned() throws Throwable {
    assertThat(reader.getName(), is("Lily"));
  }
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.