Java Junit参数化的错误结果

Java Junit参数化的错误结果,java,junit,parameterized,Java,Junit,Parameterized,我将junit测试类更改为使用Parameterized运行,以测试同一接口的两个不同实现。这是: @RunWith(Parameterized.class) public class Stack_Tests { private Stack<String> stack; public Stack_Tests(Stack<String> stack) { this.stack = stack; } @Parameters public static Colle

我将junit测试类更改为使用Parameterized运行,以测试同一接口的两个不同实现。这是:

@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() {
    ...
}
@RunWith(参数化的.class)
公共类堆栈测试{
私有堆栈;
公共堆栈测试(堆栈){
this.stack=stack;
}
@参数
公共静态集合参数(){
//要测试的两个对象
返回Arrays.asList(新对象[][{{new LinkedStack()},{new BoundedLinkedStack(MAX_SIZE)}});
}
@试验
公开无效测试(){
...
}
结果是错误的,因为我改为Parameterized。一半的测试失败(两个对象的测试结果相同),所有测试都在之前进行过

它在没有参数化的情况下工作,如下所示:

public class Stack_Tests {

private Stack<String> stack;

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

@Test
public void test() {
    ...
}
公共类堆栈测试{
私有堆栈;
@以前
public void setUp()引发异常{
stack=newlinkedstack();
}
@试验
公开无效测试(){
...
}

完整的测试类

正如您在注释中所建议的,在每次测试之前尝试重置堆栈,因为以前的测试会更改堆栈

您可以在每次单元测试之前创建一个新的堆栈实例:

@Before
public void setUp() throws Exception {
    stack = stack.getClass().newInstance();
}
尽管这有一个副作用,即类必须具有0参数构造函数

<强>注< <强>:如果一些堆栈不能具有0参数构造函数,请考虑按此调用具有构造函数的构造函数。这意味着必须将构造函数类型列表及其参数列表连同堆栈对象一起提供给单元测试类作为参数。

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


每个测试都共享堆栈,您的测试会修改堆栈。

要为所有测试获得一致的堆栈,另一种方法是在特定测试中修改堆栈之前克隆堆栈

@Test public void testPush() {
  Stack<String> myStack = (Stack<String>) stack.clone();
  myStack.push("hello");
  assertFalse(myStack.empty());
}
@Test public void testPush(){
Stack myStack=(Stack)Stack.clone();
myStack.push(“你好”);
assertFalse(myStack.empty());
}
因此,每个修改堆栈的测试都应该首先克隆它


这有点麻烦,但允许提供更复杂的堆栈作为参数(例如,带有一些元素的堆栈).

这不是很多。在切换到参数化之前,你能提供更多关于测试的信息吗?现在是什么样子?失败的测试会给你什么样的输出?我只是遵循了一个教程,除了我在问题中提出的内容之外,没有任何变化。告诉我们失败的测试以及你是如何定义这些测试的e参数。通常,错误在细节中。您可能有共享状态或其他东西。您应该向我们展示测试。可能每次测试后“堆栈”字段都没有“重置”?它可以工作,但有点丑陋和不切实际,它应该每次都重新恢复(就像正常测试一样)…如果我的对象更复杂,无法重置为其原始状态,那该怎么办?试试Spock,它比纯junit好得多,并且有很多用于此类测试的有用工具!不要误会,但我不认为提出另一个库来解决问题真的是一个解决方案…我知道,我没有将此作为答案发布。但没有对此有什么好的答案:这是junit中参数化的工作方式。您可以编写自己的@Rule或JUnitRunner“parameterized”是因为您不喜欢默认值,但其他库(如spok)已经这样做了。很好。请注意,这假设所有作为参数提供的堆栈都是空的。那么我的所有类都必须有一个空构造函数,对吗?是的,它们必须有一个空的构造函数。我将在一点时间内改进我的答案,以便您仍然可以将对象而不是类传递给测试类。请注意,这会撤消问题中作为参数给出的新BoundedLinkedStack(MAX_SIZE)的MAX_SIZE参数。
@Test public void testPush() {
  Stack<String> myStack = (Stack<String>) stack.clone();
  myStack.push("hello");
  assertFalse(myStack.empty());
}