Java JUnit为什么/如何通过带有编译器错误的测试?

Java JUnit为什么/如何通过带有编译器错误的测试?,java,junit,tdd,Java,Junit,Tdd,我刚刚开始学习TDD,我正试图以这种方式编写一个简单的项目 我正在使用Eclipse和JUnit,每次进行更改时,我都会运行相关包中的所有测试 但是,我很惊讶地看到在包资源管理器中,我的一个测试用例有一个大的红十字,表示编译器有问题。。。恼火的是,我发现我的eclipse快捷方式弄错了,没有运行所有的测试,因为它们都通过了 但当我开始胡闹时,我意识到Eclipse+JUnit似乎会运行并通过测试,即使有编译器错误 JUnit测试用例: import static org.junit.Assert

我刚刚开始学习TDD,我正试图以这种方式编写一个简单的项目

我正在使用Eclipse和JUnit,每次进行更改时,我都会运行相关包中的所有测试

但是,我很惊讶地看到在包资源管理器中,我的一个测试用例有一个大的红十字,表示编译器有问题。。。恼火的是,我发现我的eclipse快捷方式弄错了,没有运行所有的测试,因为它们都通过了

但当我开始胡闹时,我意识到Eclipse+JUnit似乎会运行并通过测试,即使有编译器错误

JUnit测试用例:

import static org.junit.Assert.*;

import org.junit.Before;
import org.junit.Test;

public class ATestCase {

    private Command command;
    private Invoker invoker;

    @Before
    public void setUp() throws Exception {

        command = new Command() {
            public void methodA(){};
            //haven't implemented methodB()
        };

        invoker = new Invoker(command);

    }

    @Test
    public void test(){
        invoker.invoke();
    }
}

interface Command{
    void methodA();
    void methodB();
}
调用程序类:

class Invoker{

    private Command command;

    public Invoker(Command command) {
        this.command = command;
        //if I invoke methodB() I get UnresolvedCompilationError
    }

    public void invoke(){
        command.methodA();
        //only if I call methodB here
        //do I get Unresolved compilation problem
//      command.methodB();
    }
}
我在测试用例的设置中创建的命令对象只实现接口的一个方法。这当然会导致Eclipse中出现编译错误警告

但是,除非我在测试用例中实际调用该方法,否则测试将通过。 如果我确实调用了该方法,那么测试将失败,并出现“未解决的编译错误”

有人能向我解释到底发生了什么事吗

******编辑******

我不知道为什么这是一个重复关闭

显然,我应该编辑这个问题以明确区别:

  • 我要重复的问题在第一行问:
“java.lang.Error:未解决”的可能原因是什么 汇编问题“

  • 我的问题的标题是我在问:
JUnit为什么/如何通过带有编译器错误的测试

正如在JUnit如何运行不应该编译的代码而不导致错误? 我完全理解
未解决编译错误
的原因,这是我代码中的明显未解决编译错误。我不明白的是错误是如何发生的(只有在我特别调用未实现的方法时才会发生)以及测试是如何通过的


可能这些问题是相关的,,但是,除非有一个具体的答案解释它们是如何相关的,否则我看不出它们是如何以任何方式重复的问题…

我假设这是出于设计:允许测试特定的方法,而不必担心编译器无论如何会发现的其他依赖关系是否得到解决
也就是说,我们不应该使用JUnit来告诉我们整个项目是否可以编译。

当一个类无法实现接口方法时,Java编译器不会拒绝该代码,而是为该方法发出字节码,从而引发运行时错误。这解释了为什么JUnit能够运行测试,以及为什么如果不调用
methodB
,测试就会通过-运行时错误不会被引发


根据,默认情况下不会发生这种情况,但需要启用Java->Debug“在编译错误时暂停执行”设置。

尝试自动关闭生成,然后选择“清除”,然后重新打开生成,然后查看是否仍会发生这种情况。@durron597感谢您的建议。我试过了,但它仍然运行并通过了测试。我认为这种行为不应该发生吗?另一个想法是,由于该方法不编译,junit无法通过注释和反射识别该方法,因此它甚至不尝试运行it@durron597我最初认为这样的事情可能已经发生了,但是你可以在screencap中看到有1/1的测试运行。安装方法也必须已经运行,否则调用程序将为null,我将得到一个NullPointerException。此代码在您的设置中是否显示相同的行为?这并不能解释它是如何工作的。如果出现编译错误,JUnit如何获取.class文件进行测试?@AndrewMedico:谢谢你提出这个问题。回答得也很好!Eclipse中的Java编译器就是这样做的。独立Javac完全拒绝无效代码。