問題描述
當我嘗試在頁面對象中使用靜態方法時,我遇到了 NullPointerExceptions 問題.如果我使用非靜態方法,它工作正常.
I'm having trouble with NullPointerExceptions when I try using static methods in a page object. If I do it with non-static methods, it works fine.
非靜態版本:
public class ComplaintPage {
private ExtendedWebDriver driver;
@FindBy(css = "[data-selector=date-received-complaint]")
public WebElement dateComplaintReceoved;
public ComplaintPage() {
driver = Browser.extendedDriver();
PageFactory.initElements(driver, this);
}
public void setComplaintDate() {
dateComplaintReceoved.sendKeys(LocalDate.now().toString());
}
}
Calling code:
ComplaintPage complaintPage = new ComplaintPage;
complaintPage.setComplaintDate();
這很好用.日期字段已設置.
This works fine. The date field is set.
靜態版
public class ComplaintPage {
private static ExtendedWebDriver driver;
@FindBy(css = "[data-selector=date-received-complaint]")
public static WebElement dateComplaintReceoved;
public ComplaintPage() {
driver = Browser.extendedDriver();
PageFactory.initElements(driver, this);
}
public void static setComplaintDate() {
* dateComplaintReceoved.sendKeys(LocalDate.now().toString());
}
}
Calling code:
ComplaintPage.setComplaintDate();
這不起作用,并在標有*"的行(訪問 WebElement 的行)上導致 java.lang.NullPointerException.
This does not work, and results in a java.lang.NullPointerException on the line marked with "*" (the line accessing the WebElement).
我有點喜歡在測試中使用像這樣的靜態方法,因為我真的看不出它有什么問題,而且它使代碼更易于閱讀.我以前在 C#/VS 中做過,但由于某種原因,我在這里遺漏了一些重要的東西.
I kind of like using static methods like this in test, since I don't really see a problem with it, and it makes the code even more easy to read. And I've done it before, in C#/VS, but for some reason I'm missing something important here.
推薦答案
NullPointerException
因為 PageFactory
的工作方式而被拋出.你看,當你創建一個 ComplaintPage
類的實例時,你正在調用它的構造函數:
NullPointerException
is thrown because of how PageFactory
works. You see, when you create an instance of ComplaintPage
class, you are invoking its constructor:
public ComplaintPage() {
driver = Browser.extendedDriver();
PageFactory.initElements(driver, this);
}
構造函數調用PageFactory
類的initElements
方法.此方法使用 Java 反射 API 初始化所有 WebElement
和 List
null
值更改為接口的實現.它還提供了一種 WebElement 的惰性實例化,這意味著 - WebElement
僅在需要時才被發現(尋找?) - 當您調用它們的操作時.
The constructor calls initElements
method of PageFactory
class. This method initializes all of WebElement
and List<WebElement
> fields with Java Reflection API. It basically changes the default null
values to implementations of the interface. It also provides sort of Lazy instantiation of the WebElement which means - WebElement
s are found (looked for?) only when needed - when you invoke operations on them.
當您創建靜態方法和靜態 WebElements 時 - 您沒有調用類的構造函數,這導致不調用 initElements
方法.
When you created static methods and static WebElements - you did not call the constructor of the class, which lead to NOT invoking the initElements
method.
使用 @FindBy
注釋的所有元素均未初始化.這就是為什么將 PageFactory 與靜態方法一起使用并不是一個好主意.
All of the elements annotated with @FindBy
were not initialized. That's why it's not a good idea to use PageFactory with static methods.
您可以在靜態方法中找到帶有經典 driver.findElement
的元素,而不是使用 PageFactory.
Instead of using PageFactory you can just find the element with classic driver.findElement
inside the static method.
public void static setComplaintDate(WebDriver driver) {
driver.findElement(By.cssSelector("[data-selector=date-received-complaint]")).sendKeys(LocalDate.now().toString());
}
這篇關于Java 和 Selenium:頁面對象中的靜態方法的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,也希望大家多多支持html5模板網!