黄瓜 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 创建
我正在为 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 创建