Baconbitz
Baconbitz

Reputation: 149

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]

Upvotes: 4

Views: 3501

Answers (3)

ARUN KUMAR
ARUN KUMAR

Reputation: 46

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.

Upvotes: 2

nperi
nperi

Reputation: 1

I can think of two approaches.

One could be with the decorator design pattern and the other one with command and macro command design pattern.

With the decorator, you can have your HelperUtils as your main class and then the other Utils can decorate it. You can have different tests with different decorators and give your tests flexibility and reuse your Utils.

With the other approach you can have each Utils to implement a Command interface. Then, define Macro Commands for each test so it's "execute" method calls every "execute" method of each Utils you want.

From what I understood I would go for the decorator approach first, but the other one could also be helpful if the decorator doesn't get you what you need.

Hope it helps.

Upvotes: 0

Ulises
Ulises

Reputation: 9635

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;
        }
    }

Upvotes: 2

Related Questions