黄瓜 Spring 和 class 配置

Cucumber Spring and class configuration

我正在为 Cucumber 和 Spring 配置而苦苦挣扎。 我正在使用页面对象模式和 BrowserFactory 编写 selenium 框架。

当我使用@ComponentScan、@Component 和@Autowire 注释时,一切正常,但是当我想在@Configuration 中使用@Bean 注释(BrowserFactory,它注册了很少的浏览器驱动程序)创建更复杂的bean 时class 它不起作用,在调试期间我在尝试自动装配的每个变量上都得到空值。

我正在使用 Spring 4.2.4,版本 1.2.4 中的所有黄瓜依赖项。

配置:

@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();
  }
  ...
}

页数:

public class Page {

  @Autowired
  private BrowserFactory browserFactory;

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

登录:

public class Login {

  @Autowired
  private LoginPage loginPage;

  public Login(){}
    ...
}

步骤:

@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);
  }
}

错误:

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

现在是有趣的部分... World class 中的 BrowserFactory 已正确自动装配!!

世界:

public class World {

  @Autowired
  private BrowserFactory browserFactory;
  ...
}

所以我会回答我自己的问题:)

问题是我在 Page 构造函数内部调用了 BrowserFactory。 看起来这个 bean 尚未创建并且导致了 NPE。

为了解决这个问题,我:

  • 在配置中添加了@Lazy 注释(所有使用此配置的元素,都在 class 中定义,以及将被 Scan 找到的元素都将创建为 Lazy)
  • 将对浏览器工厂的调用移动到@PostConstruct 方法

还有两件事可以提高 Spring 配置的可读性:

  • 在配置中添加了@ComponentScan
  • 没有构造函数参数的
  • 类 使用 @Component 和 @Scope("cucumber-glue") 注释进行注释,因此可以从 AppConfig.class
  • 中删除 bean 创建