JUnit Test传递和失败 - 使用ExpectedException和TestWatcher @ Rule进行冲突 [英] JUnit Test both passes and fails - conflict using both ExpectedException and TestWatcher @Rule's

查看:131
本文介绍了JUnit Test传递和失败 - 使用ExpectedException和TestWatcher @ Rule进行冲突的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在提出这个问题时想到了这一点,但认为这对于未来遇到同样奇怪怪癖的人来说将是一个很好的资源。把它视为对你的调试技巧的挑战。



目前使用最新的JUnit,4.12,这个特殊的测试都通过并失败 - 取决于你如何看待它。运行它将打印出错误消息 - 但尽管失败()被调用,它仍然不会被视为失败。

  import java.io.IOException; 

import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.junit.rules.TestWatcher;
import org.junit.runner.Description;

公共类TestWatcherExpectedExceptionTest {
@Rule
public TestWatcher logger = new TestWatcher(){
@Override
protected void failed(Throwable e,Description d ){
System.out.println(d +FAILED! - 你在开玩笑吧?);
e.printStackTrace();
}

@Override
protected void succeeded(描述d){
System.out.println(d +succeeded!);
}
};

@Rule
public ExpectedException thrown = ExpectedException.none();

/ **
*此测试通过和失败,具体取决于您如何看待它。
* /
@Test
public void photon()抛出IOException {
thrown.expect(IOException.class);
抛出新IOException(Hi);
}
}

作为额外的红利问题,在调试此问题时,测试突然开始成功,并调用 succeeded()方法,我不能,因为我的生活,找出原因。据我所知,代码没有任何可能产生任何影响的更改:

  import java.io .IOException; 

import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.junit.rules.TestWatcher;
import org.junit.runner.Description;

public class TestWatcherExpectedExceptionTest {
private final class TestLogger extends TestWatcher {
@Override
protected void failed(Throwable e,Description d){
System。 out.println(d +FAILED! - 你在开玩笑吗?);
e.printStackTrace();
}

@Override
protected void succeeded(描述d){
System.out.println(d +succeeded!);
}
}

@Rule
public TestWatcher watcher = new TestLogger();

@Rule
public ExpectedException thrown = ExpectedException.none();

/ **
*此测试通过和失败,具体取决于您如何看待它。
* /
@Test
public void photon()抛出IOException {
thrown.expect(IOException.class);
抛出新IOException(Hi);
}
}


解决方案

特别回答为什么第二个测试工作,以及第一个测试失败的原因在于JUnit处理规则的方式 - 显然,规则是按字母顺序处理的,基于字段名称和 TestWatcher 规则与 ExpectedException 规则不完全兼容,因为如果规则被JUnit过早解释,它将忽略预期的异常。 / p>

所以第二次测试没有失败的原因在于字段名称 - watcher 在<$ c后按字母顺序排列$ c>抛出,但是第一个测试的字段名称 logger 出现在抛出之前 。那个调试不好玩。


I figured this out during making this question, but figured it would be a good resource for future people running into the same weird quirk. Treat it as a challenge to your debugging skills.

Using the latest JUnit at the moment, 4.12, this peculiar test both passes and fails - depending how you look at it. Running it will print out the error message - but despite failed() being called, it will still not quite count as failed.

import java.io.IOException;

import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.junit.rules.TestWatcher;
import org.junit.runner.Description;

public class TestWatcherExpectedExceptionTest {
    @Rule
    public TestWatcher logger = new TestWatcher() {
        @Override
        protected void failed(Throwable e, Description d) {
            System.out.println(d + " FAILED! - are you kidding me ?");
            e.printStackTrace();
        }

        @Override
        protected void succeeded(Description d) {
            System.out.println(d + " succeeded!");
        }
    };

    @Rule
    public ExpectedException thrown = ExpectedException.none();

    /**
     * This test both passes and fails, depending how you look at it.
     */
    @Test
    public void photon() throws IOException {
        thrown.expect(IOException.class);
        throw new IOException("Hi");
    }
}

As an additional bonus question, during debugging this issue, the test suddenly started to succeed, and call the succeeded() method, and I could not, for the life of me, figure out why. As far as I could tell, there were no changes to the code that should have possibly had any impact:

import java.io.IOException;

import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.junit.rules.TestWatcher;
import org.junit.runner.Description;

public class TestWatcherExpectedExceptionTest {
    private final class TestLogger extends TestWatcher {
        @Override
        protected void failed(Throwable e, Description d) {
            System.out.println(d + " FAILED! - are you kidding me ?");
            e.printStackTrace();
        }

        @Override
        protected void succeeded(Description d) {
            System.out.println(d + " succeeded!");
        }
    }

    @Rule
    public TestWatcher watcher = new TestLogger();

    @Rule
    public ExpectedException thrown = ExpectedException.none();

    /**
     * This test both passes and fails, depending how you look at it.
     */
    @Test
    public void photon() throws IOException {
        thrown.expect(IOException.class);
        throw new IOException("Hi");
    }
}

解决方案

The peculiar answer to why the second test works, and why the first test fails at all is in the way JUnit handles rules - apparently, rules are handled in alphabetical order, based on the field name, and the TestWatcher rule is not quite compatible with the ExpectedException rule, in that it disregards the exception being expected if the rule is 'interpreted' by JUnit too soon.

So the reason the second test doesn't fail lies in the field names - watcher comes alphabetically after thrown, but the first test's field name, logger, comes before thrown. That one was not fun to debug.

这篇关于JUnit Test传递和失败 - 使用ExpectedException和TestWatcher @ Rule进行冲突的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆