Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

In Java is it possible to merge two classes so that methods from both classes can be called from one?

This maybe be an impossible task for Java, but I wondering if any of the pro's have a solution. [It's been years since I used Java, well College really]

I'm building a framework for QA. Please ask any questions or raise any flags if something doesn't make sense.

Using Selenium Webdriver, we have a driver class.

public class Driver {

private final String browser;
private final WebDriver driver;

public Driver(String browser) {
    driver = new RemoteWebDriver(new URL(Environment_address));
}

I mention this class first because it needs to be used by test classes running each test case, and libraries with additional methods. (Helper methods)

Such as

class UserPageUtils{
    private final Webdriver driver;

    public UserPageUtils(driver){
        this.driver = driver;
    }

    public void makeUsersLifeMiserable(){...}
}

and

class ActionPageUtils{
    private final Webdriver driver;

    public ActionPageUtils(driver){
        this.driver = driver
    }

    public void doSomethingCoolWithAction(){...}
}

With these examples, is there a way to merge to classes into a single class or variable? A design pattern I'm not thinking of. I have the following, how can I arrange the classes to do so that following is possible, or in similar effect.

public TestSuite extends AverageEverydayTestSuiteLikeTestNG{

@BeforeMethod
public void setUp(Object[] objects) {
    HelperUtils utils = merge('ActionPageUtils','UserPageUtils', driver);
    // Similarly in psuedo
    // HelperUtils utils = merge(new ActionPageUtils(driver), new UserPageUtils(driver));
}

@Test
public void testUserAction(HelperUtil utils){
    utils.makeUsersLifeMiserable();  //util has methods from both classes!!
    utils.doSomethingCoolWithAction();

    assert something is still passing.   
}

Is it possible to do such a thing in java? Create two wrappers in a single class. I can't wrap my head around the structuring. I feel like this is more possible in bash or something, but not sure if Java could do such a thing.

How would or could this be implemented?

Using [Java, Selenium, Groovy]

like image 548
Baconbitz Avatar asked Sep 19 '25 13:09

Baconbitz


2 Answers

Java doesn't have multiple inheritance. You can though accomplish what you want in several ways:

Pure Interfaces:

interface UserPageUtils{
    public void makeUsersLifeMiserable();
}

interface ActionPageUtils{
    public void doSomethingCoolWithAction();
}

class PageUtils implements UserPageUtils, ActionPageUtils {
   //concrete implementations
}

Facade pattern:

class UserPageUtils{
    private final Webdriver driver;

    public UserPageUtils(driver){
        this.driver = driver;
    }

    public void makeUsersLifeMiserable(){...}
}

class ActionPageUtils{
    private final Webdriver driver;

    public ActionPageUtils(driver){
        this.driver = driver
    }

    public void doSomethingCoolWithAction(){...}
}

class PageUtils{
    private final Webdriver driver;
    private final ActionPageUtils action;
    private final UserPageUtils user;

    public void doSomethingCoolWithAction(){action.doSomethingCoolWithAction();}
    public void makeUsersLifeMiserable(){user.makeUsersLifeMiserable();}
}

Or if you're using java 8, you can have default methods in your interfaces:

    interface UserPageUtils{
       public Webdriver getDriver();
       default void makeUsersLifeMiserable(){
            //somewhere here you use getDriver();
       }
    }

    interface ActionPageUtils{
       public Webdriver getDriver();
       default void doSomethingCoolWithAction() {
           //somewhere here you use getDriver();
       }
    }

    class PageUtils implements UserPageUtils, ActionPageUtils {
        private final Webdriver driver;

        @Override
        public Webdriver getDriver() {
            return driver;
        }
    }
like image 111
Ulises Avatar answered Sep 21 '25 05:09

Ulises


Use Facade Pattern like below, Instead of merge you can call constructor an HelperUtils class would be like this.

public class HelperUtils {

    ActionPageUtils actionPageUtils;
    UserPageUtils userPageUtils;
    public HelperUtils(ActionPageUtils actionPageUtils, UserPageUtils userPageUtils, Webdriver  driver) {
        this.actionPageUtils = actionPageUtils;
        this.userPageUtils = userPageUtils;
    }

    public void doSomethingCoolWithAction(){actionPageUtils.doSomethingCoolWithAction();}
    public void makeUsersLifeMiserable(){userPageUtils.makeUsersLifeMiserable();}

    public static void main(String[] args) {
        HelperUtils utils = new HelperUtils(new ActionPageUtils("Chrome"), new UserPageUtils("firefox"), driver);
        utils.makeUsersLifeMiserable();
        utils.doSomethingCoolWithAction();
    }

}

Disadvantage of this approach:

You have create new method always whenever you are updating the sub classes or merged classes.

like image 38
ARUN KUMAR Avatar answered Sep 21 '25 04:09

ARUN KUMAR