Java @使用Guice@Inject时未初始化FindBy WebElements
我目前在正确实现对象注入方面遇到一些问题。我正在用页面对象模型编写一些cumber测试。我在以下代码中得到Java @使用Guice@Inject时未初始化FindBy WebElements,java,dependency-injection,cucumber,automated-tests,guice,Java,Dependency Injection,Cucumber,Automated Tests,Guice,我目前在正确实现对象注入方面遇到一些问题。我正在用页面对象模型编写一些cumber测试。我在以下代码中得到NullPointerExceptions: public class BasePage extends LoadableComponent<BasePage>{ @Inject protected WebDriver driver //trying to inject a WebDriver instance here public BasePage
NullPointerException
s:
public class BasePage extends LoadableComponent<BasePage>{
@Inject
protected WebDriver driver //trying to inject a WebDriver instance here
public BasePage(){
PageFactory.initElements(this.driver, this);
}
@Override
protected void isLoaded() throws Error {//something here}
@Override
protected void load() {//something as well}
// some more shared methods
}
我的步骤定义登录测试:
@ScenarioScoped
public class LoginSteps {
private LoginPage login;
@Inject
LoginSteps(LoginPage login) {
this.login = login;
}
@Given("^I'm on the login page$")
public void getLoginPage() throws FileNotFoundException {
login.get();
}
@When("^I enter valid user credential")
public void enterValidUserCredential() throws FileNotFoundException {
login.enterValidLoginCredentials();
}
在我的黄瓜模块中
我使用了:
public class CucumberModule extends AbstractModule {
@Override
protected void configure() {
requestStaticInjection(BasePage.class);
}
@Provides
@ScenarioScoped
WebDriver getWebDriver(){
WebDriver driver = null;
try {
driver = Browser.loadDriver(EdgeTestProperties.getProperty("browser"));
} catch (FileNotFoundException e) {
System.err.print("Failed to load the browser preference, check test properties file....");
e.printStackTrace();
}
driver.manage().timeouts().implicitlyWait(2L, TimeUnit.SECONDS);
return driver;
}
}
当我开始运行登录测试时,只有在调用基本构造函数之后(初始化WebElement
s),才会在BasePage
上注入驱动程序。结果,WebElement
s中没有一个被初始化,因此我得到了NullPointerException
。如果我删除超级类构造函数并将驱动程序注入点更改为LoginPage
构造函数,然后通过设置驱动程序和初始化WebElement
s的方法将其传递回BasePage
,我就可以让它工作,但这似乎是错误的。有更好的方法吗?您应该使用构造函数注入。
这将解决您的问题,因为驱动程序现在在构造函数中可用
protected final Webdriver driver;
@Inject
public BasePage(WebDriver driver) {
this.driver = driver;
PageFactory.initElements(this.driver, this);
}
您应该知道,一般来说,现场注入不是首选。你发现了一个原因;另一个原因是它的构造函数注入更为详细,但它也使它在阅读代码和尝试编写测试时更清楚地了解了正在发生的事情。感谢durron597的回复,请注意,如果我通过基本构造函数注入驱动程序,我认为这意味着我应该为所有子类实现具有相同webdriver参数的构造函数,这在某种程度上反对我使用集中式共享驱动程序实例的意图?@TonyZhang为什么这样做?从使用集中式驱动程序实例的角度来看,这两种注入类型没有区别
@ScenarioScoped
应该可以为您处理这些问题;您将把参数传递到所有基类中的超级构造函数中,即@injectpublic-LoginPage(WebDriver-driver){super(driver);}
您是对的,重构代码现在一切都很好,谢谢:)@TonyZhang很高兴我能提供帮助!别忘了点击投票按钮下面的复选标记!
protected final Webdriver driver;
@Inject
public BasePage(WebDriver driver) {
this.driver = driver;
PageFactory.initElements(this.driver, this);
}