1

I'm struggling with Cucumber and Spring configuration. I'm writing selenium framework using Page Object Pattern, with BrowserFactory.

When I use @ComponentScan, @Component and @Autowire annotations everything works fine, but when I want to create a bit more complicated bean with @Bean annotation (BrowserFactory which registers few browser drivers) in @Configuration class it does not work, during debug I'm getting nulls on every single variable I'm trying to Autowire.

I'm using Spring 4.2.4, all cucumber dependencies in version 1.2.4.

Config:

@Configuration
public class AppConfig {

@Bean
@Scope("cucumber-glue")
public BrowserFactory browserFactory() {
  BrowserFactory browserFactory = new BrowserFactory();
  browserFactory.registerBrowser(new ChromeBrowser());
  browserFactory.registerBrowser(new FirefoxBrowser());
  return browserFactory;
}

@Bean(name = "loginPage")
@Scope("cucumber-glue")
public LoginPage loginPage() throws Exception {
  return new LoginPage();
}

@Bean(name = "login")
@Scope("cucumber-glue")
public Login login() {
  return new Login();
}
}

POP:

public class LoginPage extends Page {

  public LoginPage() throws Exception {
   super();
  }
  ...
}

Page:

public class Page {

  @Autowired
  private BrowserFactory browserFactory;

  public Page() throws Exception{
    ...
  }
}

Login:

public class Login {

  @Autowired
  private LoginPage loginPage;

  public Login(){}
    ...
}

Steps:

@ContextConfiguration(classes = {AppConfig.class})
public class LoginSteps {

  @Autowired
  Login login;

  public LoginSteps(){
  }

  @Given("^an? (admin|user) logs in$")
  public void adminLogsIn(Login.User user) throws Exception {
    World.currentScenario().write("Logging in as " + user + "\n");
    login.as(user);
  }
}

Error:

cucumber.runtime.CucumberException: Error creating bean with name 'LoginSteps': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: Login LoginSteps.login; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'login': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private LoginPage Login.loginPage; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'loginPage' defined in AppConfig: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [LoginPage]: Factory method 'loginPage' threw exception; nested exception is java.lang.NullPointerException

And now for the fun part... BrowserFactory in World class is properly Autowired!!

World:

public class World {

  @Autowired
  private BrowserFactory browserFactory;
  ...
}
0

1 Answer 1

3

So I'll answer my own question:)

Issue was that I was calling BrowserFactory inside of Page constructor. Looks like this bean was not yet created and was causing NPEs.

In order to fix that I:

  • Added @Lazy annotation to configuration (all elements that use this configuration, both defined in that class and those which will be found by Scan will be created as Lazy)
  • Moved call to Browser Factory to @PostConstruct method

Two more things to increase readability of Spring config:

  • Added @ComponentScan to configuration
  • Classes with no constructor parameters are annotated with @Component and @Scope("cucumber-glue") annotation so bean creation can be removed from AppConfig.class
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.