user462455
user462455

Reputation: 13588

Running JUnit tests with different data

I have a suite of unit tests. I have a static variable which gets initialized in setup() method. I want to run all my suite of unit tests with two different values of that static variable.

Static variable in setup() gets initialized to an object which is a singleton. So, I can't(I think I can't) use JUnit parametrized tests.

I have to run all the tests with one value of that static variable, and then run all the tests with other value of static variable.

Any ideas on how to do this in an elegant way if possible.

Code below if my description above is not very easy to understand

public class MyClassTest{
      private static final Dep_class dep_obj;

      public static void setup(){
               dep_obj = Dep_class.getInstance("VALUE_1");
               //You can have only instance of Dep_class at any time.
               //So for second run I need to do a 
               //dep_obj = Dep_class.getInstance("VALUE_2") and run my tests.
      }

      public void test_mymethod(){
          //do something with dep_obj
      }

Upvotes: 0

Views: 836

Answers (2)

Evgeniy Dorofeev
Evgeniy Dorofeev

Reputation: 136012

Try this

@RunWith(Parameterized.class)
public class MyClassTest {
    private Object dep_obj;

    public MyClassTest(String val) {
        dep_obj = val;
    }

    @Parameters
    public static Collection<?> data() {
        Object[][] data = { { "val1" }, { "val2" }, { "val3" } };
        return Arrays.asList(data);
    }

    @Test
    public void test() {
        System.out.println(dep_obj);
    }
}

Upvotes: 2

josh-cain
josh-cain

Reputation: 5226

So first of all, I would question why you have a singleton that is initialized in this way. It seems as if adding an argument to your .getInstance(String s) method would add ambiguity and unexpected behavior, as this String argument will just be disregarded after instantiation (unless you're re-instantiating it if the type changes, in which case it will be highly unpredictable at runtime).

In any case, an easy way to do this would be to abstract the test_mymethod() to a parent class and have two child test classes that each instantiate a different instance of the singleton. Since your JVM will not restart, you'll also need something like PowerMock to reset the singleton to a pre-loaded state before running any tests.

So the parent class would look like so (JUnit annotations added):

public abstract class MyAbstractTestClass {
      private final Dep_class dep_obj;

      @Before
      public abstract void setup(){
            // Begin by ensuring that the singleton instance is initialized to null - 
            // this is highly important, since subclasses will not be able to rely on 
            // an un-initialized state
            Whitebox.setInternalState(dep_obj.getInstance(/*default, arbitrary, or null value*/, "instance", null);

            // Now leave the actual singleton initialization to child classes
            dep_obj = getSingleton();
      }

      public abstract Dep_class getSingleton();

      @Test
      public void test_mymethod(){
          //do something with dep_obj
      }
}

I made a few assumptions with Powermock - namely that your singleton properly checks to see if the instance is null and if so, initializes it. In this case, I'm assuming that the variable name for your instance is "instance". Next, your child classes would look like this:

public class MyTestClass1 extends MyAbstractTestClass {

      @Override
      public void Dep_class getSingleton() {
               return Dep_class.getInstance("VALUE_1");
      }
}

public class MyTestClass2 extends MyAbstractTestClass {

      @Override
      public void Dep_class getSingleton() {
               return Dep_class.getInstance("VALUE_2");
      }
}

Again, I would strongly encourage you to re-think implementing a singleton in this way. Singletons should be rarely used anyway - an implementation like this on top of a questionable design pattern is an eyebrow raiser. This question goes over some good guidelines for usage - make sure that your singleton fits this criteria.

Upvotes: 1

Related Questions