使用 Guice @Inject 时未初始化 @FindBy WebElements
@FindBy WebElements not initialized when using Guice @Inject
我目前在正确实施对象注入方面遇到了一些问题。我正在使用页面对象模型编写一些 Cucumber 测试。我在以下代码中得到 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
}
上面是我的 BasePage
class,LoginPage
extends BasePage
如下
public class LoginPage extends BasePage {
@FindBy(id="login_username")
private WebElement userNameField;
@FindBy(id="login_password")
private WebElement passWordField;
@FindBy(id="login_database")
private WebElement dataBase;
public void enterValidLoginCredentials() throws FileNotFoundException {
userNameField.sendKeys(EdgeTestProperties.getProperty("userName"));
passWordField.sendKeys(EdgeTestProperties.getProperty("password"));
dataBase.sendKeys(EdgeTestProperties.getProperty("db"));
}
//some more tests here
}
我的步骤定义登录测试:
@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();
}
在我的 CucumberModule
中,我使用了:
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;
}
}
当我开始 运行 登录测试时,BasePage
上的驱动程序的 @Inject
ion 仅在调用基本构造函数之后发生( WebElement
的初始化秒)。结果, WebElement
中的 none 被初始化,所以我得到 NullPointerException
。如果我删除超级 class 构造函数并将驱动程序注入点更改为 LoginPage
构造函数并通过设置驱动程序和初始化 WebElement
s,但这似乎是错误的。有没有更好的办法?
你应该使用构造函数注入。
这将解决您的问题,因为驱动程序现在可以在构造函数中使用。
protected final Webdriver driver;
@Inject
public BasePage(WebDriver driver) {
this.driver = driver;
PageFactory.initElements(this.driver, this);
}
你应该知道,一般来说,字段注入不是首选。你发现了一个原因;另一个原因是它 hard to test. 构造函数注入更冗长,但它也使阅读代码和尝试编写测试时发生的事情更加清晰。
我目前在正确实施对象注入方面遇到了一些问题。我正在使用页面对象模型编写一些 Cucumber 测试。我在以下代码中得到 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
}
上面是我的 BasePage
class,LoginPage
extends BasePage
如下
public class LoginPage extends BasePage {
@FindBy(id="login_username")
private WebElement userNameField;
@FindBy(id="login_password")
private WebElement passWordField;
@FindBy(id="login_database")
private WebElement dataBase;
public void enterValidLoginCredentials() throws FileNotFoundException {
userNameField.sendKeys(EdgeTestProperties.getProperty("userName"));
passWordField.sendKeys(EdgeTestProperties.getProperty("password"));
dataBase.sendKeys(EdgeTestProperties.getProperty("db"));
}
//some more tests here
}
我的步骤定义登录测试:
@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();
}
在我的 CucumberModule
中,我使用了:
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;
}
}
当我开始 运行 登录测试时,BasePage
上的驱动程序的 @Inject
ion 仅在调用基本构造函数之后发生( WebElement
的初始化秒)。结果, WebElement
中的 none 被初始化,所以我得到 NullPointerException
。如果我删除超级 class 构造函数并将驱动程序注入点更改为 LoginPage
构造函数并通过设置驱动程序和初始化 WebElement
s,但这似乎是错误的。有没有更好的办法?
你应该使用构造函数注入。
这将解决您的问题,因为驱动程序现在可以在构造函数中使用。
protected final Webdriver driver;
@Inject
public BasePage(WebDriver driver) {
this.driver = driver;
PageFactory.initElements(this.driver, this);
}
你应该知道,一般来说,字段注入不是首选。你发现了一个原因;另一个原因是它 hard to test. 构造函数注入更冗长,但它也使阅读代码和尝试编写测试时发生的事情更加清晰。