我目前正在解决正确实施对象注入的问题。我正在使用Page Objects Model编写一些Cucumber测试。我在以下代码中获得了NullPointerException
:
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
课程,LoginPage
扩展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;
}
}
当我开始运行登录测试时,@Inject
上的驱动程序的BasePage
仅在调用基本构造函数(WebElement
s的初始化)之后发生。结果,WebElement
没有被初始化,所以我得到NullPointerException
。如果我删除超类构造函数并将驱动程序注入点更改为LoginPage
构造函数并通过设置驱动程序和初始化BasePage
的方法将其传递回WebElement
,我可以使它工作。但是,这似乎是错误的。还有更好的方法吗?
答案 0 :(得分:1)
这将解决您的问题,因为驱动程序现在可以在构造函数中使用。
protected final Webdriver driver;
@Inject
public BasePage(WebDriver driver) {
this.driver = driver;
PageFactory.initElements(this.driver, this);
}
您应该意识到,一般来说,不优选进样。你发现了一个原因;另一个原因是它是hard to test.构造函数注入更加冗长,但它也使得在读取代码和尝试编写测试时更加清晰。