Kaloyan Roussev
Kaloyan Roussev

Reputation: 14711

Java: How can I refactor a method to a class and then use its parameters in other classes?

3 weeks of experience with Java here. I have these two classes - AppTest and AppTest2 and I have the same code in both of them:

Here is my code:

public class Apptest/AppTest2 {
     public WebDriver driver;
     public WebDriverWait wait;

     @DataProvider(name = "dataProvider")
     public Object[][] setUp() throws Exception {
     File firefoxPath = new File(System.getProperty("lmportal.deploy.firefox.path", "C:\\Program Files (x86)\\Mozilla Firefox\\firefox.exe"));
     FirefoxBinary ffox = new FirefoxBinary(firefoxPath);
     ffox.setEnvironmentProperty("DISPLAY", ":20");
     driver = new FirefoxDriver(ffox, null);
     wait = new WebDriverWait(driver, timeoutInSeconds );
     Object[][] data = new Object[1][2];
     data[0][0] = driver;
     data[0][1] = wait;
     return data;
 }

  @Parameters({ "driver", "wait" })
  @Test(dataProvider = "dataProvider")
  public void twoUsersSignUp(WebDriver driver, WebDriverWait wait) throws InterruptedException{

       //test here

     }
}

How can I take this code out (setUp()), make it a class and then pass those variables to the next void "twoUsersSignUp"

EDIT: Im not looking for automatic solution, I just want to refactor this, so I dont have the same code in both classes

EDIT2: After I implemented the accepted answer's solution, I now have a problem with passing the variable "driver" to the next method in the first class:

     @AfterClass
     public void quit () {
         driver.quit();
     }

How do I do that?

EDIT3: This is the @AfterClass solution:

     @SuppressWarnings("deprecation")
     @Configuration 
     @AfterClass
     public static void quit (@Optional WebDriver driver) {
         driver.quit();
     }

EDIT4: actually EDIT3 doesnt work, it just hides the errors from Eclipse. I still can't access "driver" :(

EDIT5: I decided that I dont need to have it in an AfterClass TestNG annotation, so I removed all the unnecessary stuff and it now looks like this:

     public static void quit (WebDriver driver) {
         driver.quit();
     }

and the variable has been declared this way:

public static WebDriver driver;

but still it doesnt work

EDIT6: fixed this by actually calling the method in the test code. Beforehand I didnt have to call it, because testng.xml had it called, but after I removed the @AfterTest annotation, it had been excluded from there!

Upvotes: 1

Views: 254

Answers (4)

Amin Abu-Taleb
Amin Abu-Taleb

Reputation: 4511

Initialize your testData class like this

public class ApptestData{
 public WebDriver driver;
 public WebDriverWait wait;

 public ApptestData() throws Exception {
 File firefoxPath = new File(System.getProperty("lmportal.deploy.firefox.path", "C:\\Program Files (x86)\\Mozilla Firefox\\firefox.exe"));
 FirefoxBinary ffox = new FirefoxBinary(firefoxPath);
 ffox.setEnvironmentProperty("DISPLAY", ":20");
 driver = new FirefoxDriver(ffox, null);
 wait = new WebDriverWait(driver, timeoutInSeconds );
 Object[][] data = new Object[1][2];
 data[0][0] = driver;
 data[0][1] = wait;
 twoUsersSignUp(data);
 return data;
 }
}

And then use that object in your test classes

    public class Apptest/AppTest2 {

     @Test
     public void twoUsersSignUp() throws InterruptedException{

       AppTestData data = new AppTestData();
       //test here

     }

    }

Upvotes: 1

Sergey Kalinichenko
Sergey Kalinichenko

Reputation: 726489

You cannot convert a method to a class, but you can move a method to a place from which it would be shared by both Apptest and AppTest2: create a base class, and make the Apptest and AppTest2 classes extend it.

public abstract class AbstractAppTest {
    public WebDriver driver;
    public WebDriverWait wait;

    @DataProvider(name = "dataProvider")
    public Object[][] setUp() throws Exception {
        File firefoxPath = new File(System.getProperty("lmportal.deploy.firefox.path", "C:\\Program Files (x86)\\Mozilla Firefox\\firefox.exe"));
        FirefoxBinary ffox = new FirefoxBinary(firefoxPath);
        ffox.setEnvironmentProperty("DISPLAY", ":20");
        driver = new FirefoxDriver(ffox, null);
        wait = new WebDriverWait(driver, timeoutInSeconds );
        Object[][] data = new Object[1][2];
        data[0][0] = driver;
        data[0][1] = wait;
        twoUsersSignUp(data);
        return data;
    }
    public abstract void twoUsersSignUp(@Optional Object[][] data) throws InterruptedException; 
}
public class Apptest extends AbstractAppTest {
    public void twoUsersSignUp(@Optional Object[][] data) throws InterruptedException {
        ...
    }
}
public class AppTest2 extends AbstractAppTest {
    public void twoUsersSignUp(@Optional Object[][] data) throws InterruptedException {
        ...
    }
}

Now the code of the setUp method does not need to be repeated, and it uses the implementation of the twoUsersSignUp method provided in each of the two subclasses of AbstractAppTest.

Upvotes: 2

Andrea Ligios
Andrea Ligios

Reputation: 50203

The kind of refactoring you are looking for does not exists yet, at least on Eclipse.

A workaround to do it manually is explained here

By the way, in Eclipse by pressing ALT SHIFT T you will find all the current available possibilities to refactor your existent code, by extracting methods, classes etc.

Upvotes: 0

Lai
Lai

Reputation: 482

You can't just convert a method to a class.

However, you can create new objects or modify existing objects.

Upvotes: 1

Related Questions