使用Guice @Inject

时间:2016-07-07 01:50:56

标签: java dependency-injection cucumber automated-tests guice

我目前正在解决正确实施对象注入的问题。我正在使用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,我可以使它工作。但是,这似乎是错误的。还有更好的方法吗?

1 个答案:

答案 0 :(得分:1)

您应该使用构造函数注入。

这将解决您的问题,因为驱动程序现在可以在构造函数中使用。

protected final Webdriver driver;

@Inject
public BasePage(WebDriver driver) {
    this.driver = driver;
    PageFactory.initElements(this.driver, this);
}

您应该意识到,一般来说,不优选进样。你发现了一个原因;另一个原因是它是hard to test.构造函数注入更加冗长,但它也使得在读取代码和尝试编写测试时更加清晰。