dblouis
dblouis

Reputation: 608

Wrong results with Junit parameterized

I changed a junit test class to run with Parameterized to test two different implementations of the same interface. Here it is :

@RunWith(Parameterized.class)
public class Stack_Tests {

private Stack<String> stack;

public Stack_Tests(Stack<String> stack) {
    this.stack = stack;
}

@Parameters
public static Collection<Object[]> parameters() {
    // The two object to test
    return Arrays.asList(new Object[][] { { new LinkedStack<String>() }, { new BoundedLinkedStack<String>(MAX_SIZE) } });
}

@Test
public void test() {
    ...
}

The results are wrong since I changed to Parameterized. Half of the tests fail (the same for the two objects), all of them worked before.

It works without Parameterized like this :

public class Stack_Tests {

private Stack<String> stack;

@Before
public void setUp() throws Exception {
    stack = new LinkedStack<String>();
}

@Test
public void test() {
    ...
}

The complete test class here

Upvotes: 2

Views: 644

Answers (3)

Genti Saliu
Genti Saliu

Reputation: 2723

As you suggested in the comments, try resetting the stack before every test, since previous tests change it.

You can create a new stack instance before every unit test:

@Before
public void setUp() throws Exception {
    stack = stack.getClass().newInstance();
}

Though this has the side effect that your classes must have 0-argument constructors.

Note: If some of your stacks can not have 0-argument constructors, consider invoking the constructor with arguments as per this SO answer. This means that you must provide the constructor types list and its arguments list along with the stack object to the unit test class as parameters. Then you can do:

@Before
public void setUp() throws Exception {
    stack = stack.getClass().getDeclaredConstructors(typesList).newInstance(argsList);
}

Upvotes: 3

J&#233;r&#233;mie B
J&#233;r&#233;mie B

Reputation: 11022

add :

@Before
public void setUp() throws Exception {
    stack.clear();
}

the stack is shared for each test, and your tests modify the stack.

Upvotes: 2

avandeursen
avandeursen

Reputation: 8668

To get a consistent stack for all tests, an alternative approach is to clone the stack before modifying it in a particular test.

@Test public void testPush() {
  Stack<String> myStack = (Stack<String>) stack.clone();
  myStack.push("hello");
  assertFalse(myStack.empty());
}

Thus, every test that modifies the stack should first clone it.

This is a little more cumbersome, but allows to provide more sophisticated stacks as parameters (e.g., ones with some elements to start with).

Upvotes: 1

Related Questions