Вложенные классы Java11 при использовании Fluent Design Structure для кода - PullRequest
1 голос
/ 08 ноября 2019

Таким образом, я унаследовал проект автоматизации (на основе JAVA11 с использованием Selenium / TestNG), и они хотят, чтобы он был реорганизован для использования Fluent Design для базы кода, чтобы некодерам было легче начать тестовую сборку. Имеет смысл ... однако ... они используют вложенные JAVA-классы на всей своей фабрике карт страниц и хотели бы продолжать в том же духе.

Я хорошо разбираюсь в C #, но не так много в JAVA и во вложенных классах,Ниже приведен пример того, о чем я говорю. В основном им нужен дизайн Fluent, поэтому, если им нужно получить доступ к вложенному классу, они могут вызвать его в событии using родительского класса, чтобы он не влиял на цепочку.

Я искал примерыэто с Селеном, но с трудом найти некоторые. Любая помощь приветствуется.

\\Code Base

public class UserAdminPage
{
    @SuppressWarnings("unused")
    private static WebElement element = null;

    public UserAdminPage(RemoteWebDriver driver)
    {
        PageFactory.initElements(driver, this);
    }

    public static UserAdminPage using(RemoteWebDriver driver) 
    {
        return new UserAdminPage(driver);
    }

    public static class AddEditUserInformation
    {
        @FindBy(name = "firstName")
        public WebElement FirstName_txtbx;
        public UserAdminPage FirstName_txtbx(String firstname)
        {
            this.FirstName_txtbx.sendKeys(firstname);
            return this;
        }       

        @FindBy(name = "lastName")
        public WebElement LastName_txtbx;
        public AddEditUserInformation LastName_txtbx(String lastname)
        {
            this.LastName_txtbx.sendKeys(lastname);
            return this;
        }

    }

    @FindBy(id = "AccountsList")
    public WebElement AccountName_dropdwn;
    public void AccountName_dropdwn()
    {
        this.AccountName_dropdwn.click();
    }

    @FindBy(id = "Save_button")
    public WebElement Save_btn;
    public void Save_btn()
    {
        this.Save_btn.click();
    }


}

\\Test Event
UserAdminPage.using(driver).AccountName_dropdwn()
                           .AddEditUserInformation.FirstName_txtbx("John")
                           .AddEditUserInformation.LastName_txtbx("Doe")
                           .Save_btn()

Ответы [ 2 ]

2 голосов
/ 09 ноября 2019

Как указал Заг в своем ответе, «вложенные классы», о которых вы говорите, фактически являются «обычными классами» (так как они являются статическими), единственное необычное здесь заключается в том, что они помещаются в тот же файл, что и другие классы. .

Вы не можете иметь хороший "плавный дизайн" с классами, которые не имеют ничего общего (без общего интерфейса, без использования обобщений), если вы не готовы пойти на некоторые жертвы. Приведенный ниже код демонстрирует компромисс с использованием методов «on»: есть цепочка, но вам нужно будет вручную переместить цепочку из одного класса в другой (обычно это то, что хороший «беглый дизайн» скрывает и автоматически делает длявам, так что вам не нужно об этом думать).

Обратите внимание, что приведенный ниже код компилируется и может быть выполнен (с помощью метода "main") - именно так ваш код должен быть представлен в вашем вопросе) если это вообще возможно.

package so;
public class UserAdminPage {

    public static void main(String[] args) {

        // test code
        System.out.println("Start test.");
        UserAdminPage.using(new RemoteWebDriver())
            .AccountName_dropdwn()
            .onAddEditUserInformation()
            .FirstName_txtbx("John")
            .LastName_txtbx("Doe")
            .onUserAdminPage()
            .Save_btn();
        System.out.println("Finished test.");
    }

    public static UserAdminPage using(RemoteWebDriver driver) {
        return new UserAdminPage(driver);
    }

    private WebElement AccountName_dropdown = new WebElement();
    private WebElement Save_btn = new WebElement();

    public UserAdminPage(RemoteWebDriver driver) {
        PageFactory.initElements(driver, this);
    }

    public UserAdminPage AccountName_dropdwn() {
        AccountName_dropdown.click();
        return this;
    }

    public UserAdminPage Save_btn() {
        Save_btn.click();
        return this;
    }

    public AddEditUserInformation onAddEditUserInformation() {
        return new AddEditUserInformation(this);
    }

    // nested class

    public static class AddEditUserInformation {

        private UserAdminPage page;

        public WebElement FirstName_txtbx = new WebElement();
        public WebElement LastName_txtbx = new WebElement();

        public AddEditUserInformation(UserAdminPage page) {
            this.page = page;
        }

        public AddEditUserInformation FirstName_txtbx(String firstname) {
            this.FirstName_txtbx.sendKeys(firstname);
            return this;
        }       

        public AddEditUserInformation LastName_txtbx(String lastname) {
            this.LastName_txtbx.sendKeys(lastname);
            return this;
        }

        public UserAdminPage onUserAdminPage() {
            return page;
        }
    }

    // external classes

    public static class WebElement {
        public void sendKeys(String keys) {}
        public void click() {}
    }
    public static class RemoteWebDriver {}
    public static class PageFactory {
        public static void initElements(RemoteWebDriver driver, UserAdminPage page) {}
    }

}
2 голосов
/ 09 ноября 2019

Статический открытый внутренний класс - это, по сути, совершенно отдельный класс, который мог бы легко находиться в другом файле.

Вы вызываете AccountName_dropdwn и затем пытаетесь вызвать метод для его возвращаемого значения, что является недействительным. Вы пытаетесь вызвать метод AddEditUserInformation.FirstName_txtbx, но это (нестатическая) функция-член AddEditUserInformation, поэтому ее можно вызывать только для экземпляра этого класса. Нигде в вашем коде вы не создадите его.

Если бы метод AccountName_dropdwn возвратил объект AddEditUserInformation, ваш код, вероятно, будет работать, я думаю. Я предполагаю, что ненужная квалификация имени метода не помешает его работе, но это настолько необычно, что я не уверен.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...