`

Junit参数化测试报No tests found Matching Methed

阅读更多
  今天在用Junit进行单元测试的时候,遇到一个诡异的问题。测试代码如下:

Java类:Calculate.java
public class Calculate {
    public int sum(int var1, int var2) {
        System.out.println("Adding values " + var1 + " + " + var2);
        return var1 + var2;
    }
    
    public int subtract(int var1,int var2){
        System.out.println("Subtract values "+ var1+" - "+ var2);
        return var1-var2;
    }
}


测试类:ParameterizedCalculateTest.java
@RunWith(Parameterized.class)
public class ParameterizedCalculateTest {
    private int expected;
    private int var1;
    private int var2;

    public ParameterizedCalculateTest(int expected, int var1, int var2) {
        this.expected = expected;
        this.var1 = var1;
        this.var2 = var2;
    }

    @Parameters
    public static Collection prepareParamters() {
        return Arrays.asList(new Integer[][] { { 3, 1, 2 }, { 5, 2, 3 },

        { 7, 3, 4 }, { 9, 4, 5 } });

    }

    @Test
    public void testSum() {
        System.out.println("Additions with parameters,first:" + var1 + " and second:" + var2);
        Calculate cal = new Calculate();
        Assert.assertEquals(expected, cal.sum(var1, var2));
    }

}


错误堆栈如下:
java.lang.Exception: No tests found matching Method testSum(com.milan.gjunit.ParameterizedCalculateTest) from org.junit.internal.requests.ClassRequest@739495b8
	at org.junit.internal.requests.FilterRequest.getRunner(FilterRequest.java:40)
	at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.<init>(JUnit4TestReference.java:33)
	at org.eclipse.jdt.internal.junit4.runner.JUnit4TestMethodReference.<init>(JUnit4TestMethodReference.java:25)
	at org.eclipse.jdt.internal.junit4.runner.JUnit4TestLoader.createTest(JUnit4TestLoader.java:54)
	at org.eclipse.jdt.internal.junit4.runner.JUnit4TestLoader.loadTests(JUnit4TestLoader.java:38)
	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:452)
	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)


  刚开始看到异常信息:"java.lang.Exception: No tests found matching Method testSum",猜测难道测试类的方法名要和对应java类中的方法名一样么?试下呗,于是将测试类改为:
@RunWith(Parameterized.class)
public class ParameterizedCalculateTest {
    private int expected;
    private int var1;
    private int var2;

    public ParameterizedCalculateTest(int expected, int var1, int var2) {
        this.expected = expected;
        this.var1 = var1;
        this.var2 = var2;
    }

    @Parameters
    public static Collection prepareParamters() {
        return Arrays.asList(new Integer[][] { { 3, 1, 2 }, { 5, 2, 3 },

        { 7, 3, 4 }, { 9, 4, 5 } });

    }

    @Test
    public void sum() {
        System.out.println("Additions with parameters,first:" + var1 + " and second:" + var2);
        Calculate cal = new Calculate();
        Assert.assertEquals(expected, cal.sum(var1, var2));
    }

}

结果还是不行。。。
果断搜索之,搜到stackoverflow上有类似的问题:http://stackoverflow.com/questions/12798079/initializationerror-with-eclipse-and-junit4-when-executing-a-single-test/18438718#18438718
于是乎抱着试试看的想法,扩展Parameterized.Java如下:
public class IDECompatibleParameterized extends Parameterized {

    public IDECompatibleParameterized(Class<?> klass) throws Throwable {
        super(klass);
    }

    public void filter(Filter filter) throws NoTestsRemainException {
        super.filter(new FilterDecorator(filter));
    }

   /**
     * Running single test in case of parameterized test causes issue as explained in
     * http://youtrack.jetbrains.com/issue/IDEA-65966
     *
     * As a workaround we wrap the original filter and then pass it a wrapped description
     * which removes the parameter part (See deparametrizedName)
     */
    private static class FilterDecorator extends Filter {
        private final Filter delegate;

        private FilterDecorator(Filter delegate) {
            this.delegate = delegate;
        }

        @Override
        public boolean shouldRun(Description description) {
            return delegate.shouldRun(wrap(description));
        }

        @Override
        public String describe() {
            return delegate.describe();
        }
    }

    private static Description wrap(Description description) {
        String name = description.getDisplayName();
        String fixedName = deparametrizedName(name);
        Description clonedDescription =
                Description.createSuiteDescription(fixedName,description.getAnnotations().toArray(new Annotation[0]));
        for(Description child : description.getChildren()){
            clonedDescription.addChild(wrap(child));
        }
        return clonedDescription;
    }

    private static String deparametrizedName(String name) {
        //Each parameter is named as [0], [1] etc
        if(name.startsWith("[")){
            return name;
        }

        //Convert methodName[index](className) to
        //methodName(className)
        int indexOfOpenBracket = name.indexOf('[');
        int indexOfCloseBracket = name.indexOf(']')+1;
        return name.substring(0,indexOfOpenBracket).concat(name.substring(indexOfCloseBracket));
    }
}


PS:装饰器模式用的很赞。。。
然后再把测试类改为:
@RunWith(IDECompatibleParameterized.class)
public class ParameterizedCalculateTest {
    private int expected;
    private int var1;
    private int var2;

    public ParameterizedCalculateTest(int expected, int var1, int var2) {
        this.expected = expected;
        this.var1 = var1;
        this.var2 = var2;
    }

    @Parameters
    public static Collection prepareParamters() {
        return Arrays.asList(new Integer[][] { { 3, 1, 2 }, { 5, 2, 3 },

        { 7, 3, 4 }, { 9, 4, 5 } });

    }

    @Test
    public void sum() {
        System.out.println("Additions with parameters,first:" + var1 + " and second:" + var2);
        Calculate cal = new Calculate();
        Assert.assertEquals(expected, cal.sum(var1, var2));
    }

}

修改点为:@RunWith(IDECompatibleParameterized.class)
果断Pass。
   记录下,顺便对国际友人表示感谢,希望对遇到类似问题的朋友有所帮助。
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics