【问题标题】:JUnit @Rule to pass parameter to testJUnit @Rule 将参数传递给测试
【发布时间】:2010-06-17 10:01:19
【问题描述】:

我想创建@Rule 来做这样的事情

@Test public void testValidationDefault(int i) throws Throwable {..}

其中 i 是 @Rule 传递给测试的参数。

但我确实得到了

java.lang.Exception: Method testValidationDefault should have no parameters

有没有办法绕过它,在@Rule中设置i参数?

【问题讨论】:

  • @Rule 是 JUnit 提供的注解吗?它应该放在哪里?
  • 仅供参考 - 我使用的是 junit、hamcrest 和 junitparams jar 文件。我忘记在我的测试类名称之前使用此代码@RunWith(JUnitParamsRunner.class)。然后,我得到了你得到的错误 - java.lang.Exception: Method testMethod should have no parameters

标签: java parameters junit junit-rule


【解决方案1】:

正如 IAdapter 所说,你不能使用规则传递参数,但你可以做类似的事情。

实现一个规则来保存所有参数值,并为每个参数值评估一次测试并通过方法提供值,以便测试可以从规则中提取它们。

考虑这样的规则(伪代码):

public class ParameterRule implements MethodRule{
    private int parameterIndex = 0;
    private List<String> parameters;
    public ParameterRule(List<String> someParameters){ 
        parameters = someParameters;
    }

    public String getParameter(){
        return parameters.get(parameterIndex);
    }

    public Statement apply(Statement st, ...){
        return new Statement{
             public void evaluate(){
                 for (int i = 0; i < parameters.size(); i++){
                     int parameterIndex = i;
                     st.evaluate()
                 }      
             }
        }
    }
}

您应该可以在这样的测试中使用它:

 public classs SomeTest{
     @Rule ParameterRule rule = new ParameterRule(ArrayList<String>("a","b","c"));

     public void someTest(){
         String s = rule.getParameter()

         // do some test based on s
     }
 }

【讨论】:

【解决方案2】:

我使用@Parameters@RunWith(value = Parameterized.class) 将值传递给测试。一个例子可以在here找到。

我不知道@Rule注解,但是在阅读this post之后,我认为它除了将参数传递给测试之外还有另一个目的:

如果在您的测试类中,您创建了一个指向实现 MethodRule 接口的对象的字段,并通过添加 @Rule 实现将其标记为作为规则处理,那么 JUnit 将为每个测试它将运行,允许您围绕测试执行添加其他行为。

我希望这会有所帮助。

【讨论】:

  • 找不到您提供的最后一个网址。
  • @MarcoS 有关如何使用规则注释的其他示例的链接已损坏。更新你的答案。
  • @OO7 感谢您的评论:我删除了附加示例的链接,因为作者显然删除了该页面。
【解决方案3】:

最近我开始了zohhak 项目。它可以让你编写带有参数的测试(但它是一个跑步者,而不是一个规则):

@TestWith({
   "25 USD, 7",
   "38 GBP, 2",
   "null,   0"
})
public void testMethod(Money money, int anotherParameter) {
   ...
}

【讨论】:

    【解决方案4】:

    需要注意的是,不能直接将参数传递给测试方法已不再正确。现在可以使用Theories@DataPoints/@DataPoint 来完成。

    例如:

    @RunWith(Theories.class)
    public class TestDataPoints {
    
        @DataPoints
        public static int [] data() {
            return new int [] {2, 3, 5, 7};
        }
    
        public int add(int a, int b) {
            return a + b;
        }
    
        @Theory
        public void testTheory(int a, int b) {
            System.out.println(String.format("a=%d, b=%d", a, b));
            assertEquals(a+b, add(a, b));
        }
    }
    

    输出:

    a=2, b=2 a=2, b=3 a=2, b=5 a=2, b=7 a=3, b=2 a=3, b=3 a=3, b=5 a=3, b=7 a=5, b=2 a=5, b=3 a=5, b=5 a=5, b=7 a=7, b=2 a=7, b=3 a=7, b=5 a=7, b=7

    测试通过。

    【讨论】:

    • 这不允许有多个数据点,所以这个功能在 99% 的情况下是毫无用处的。
    • 您可以拥有多个@DataPoints。如果它们属于不同类型,那么它们会被自动处理,如果它们属于相同类型,您可以使用parameter supplier。设置起来有点麻烦,但设置后使用起来相对简单。
    • 仍然比 TestNG 中的 DataProviders 复杂和繁琐得多。虽然看起来很明显,这个功能非常有用..
    【解决方案5】:

    做不到,即使使用@Rule,也无法将参数传递给测试方法。

    【讨论】:

    • 查看我的回复以了解传递参数的方法,尽管不使用@Rule
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-01-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-05-25
    • 2015-03-14
    • 1970-01-01
    相关资源
    最近更新 更多