문제

I've just started learning about TDD and am trying to write a simple project that way.

I'm using Eclipse and JUnit, and every time I make a change I run all the tests in the relevant package.

But then I'm very surprised to see in the package explorer that one of my test cases has a big red cross indicating a compiler problem... Annoyed I figured that I got my eclipse shortcuts mixed up and haven't been running all the tests, as they are all passing.

But when I start fiddling about, I realise that it seems Eclipse + JUnit will run and pass tests even if there are compiler errors...

The JUnit test case:

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();
}

The Invoker class:

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();
    }
}

The command object I create in setUp in the test case only implements one of the interface's methods. This of course causes a compilation error warning in Eclipse.

However unless I actually call that method in the test case, the test passes. If I do call the method, then the test fails with 'unresolved compilation error'.

enter image description here

Can anyone explain to me what exactly is going on?

******EDIT******

I'm not sure why this was closed as a duplicate.

Apparently I'm supposed to edit this question to make the difference clear:

  • Well the question I'm supposed to be duplicating asks in the first line:

What are the possible causes of a "java.lang.Error: Unresolved compilation problem"?

  • The title of my question states I'm asking:

Why/how does JUnit pass tests with compiler errors?

As in how can code which shouldn't compile be run by JUnit without causing errors? I fully understand the causes of the Unresolved Compilation Error, it's the obvious unresolved compilation error in my code. What I don't understand is how the error doesn't always occur (it only occurs when I specifically call an unimplemented method) and how the tests pass?!

It may be that these issues are related, but unless there is a specific answer explaining how they are related I fail to see how they are in any way duplicate questions...

도움이 되었습니까?

해결책

When a class fails to implement an interface method, the Java compiler does not reject the code but instead emits bytecode for the method that will raise the runtime error seen. This explains why JUnit is able to run the tests and why the test passes if you don't call methodB - the runtime error does not get raised.

Per this page, this does not occur by default but requires that you have the Java -> Debug 'Suspend execution on compilation errors' setting enabled.

다른 팁

I'm assuming that is by design: to allow for testing specific methods without having to worry about whether other dependencies which the compiler would pick up on anyway are resolved or not.
i.e. we shouldn't be using JUnit to tell us whether our entire project can compile or not.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top