Search code examples
javajunitjunit-rule

JUnit + Java + ErrorCollector issue


I'm having some trouble with ErrorCollectors in Java.

I have some code, which is comparing two values. If the values match, a pass is the result. If the values do not match, a fail. Sounds simple. So I created a basic test case:

public class CB_Test {


    @Rule
    public ErrorCollector collector = new ErrorCollector();

    @Before
    public void setUp() {
        //steps = new WebDriverSteps(new FirefoxDriver());
        //steps = new WebDriverSteps();
    }

    @Test
    public void testme() {
        String checkMe;
        String value;

        checkMe = "1234";
        value   = "2234";

        System.out.println("value coming in : " + value);
        System.out.println("value to check  : " + checkMe);
        collector.checkThat("Check values match", value, is(checkMe));

    }
}

Which behaves exactly as I wanted it to. However I wanted to then make this code able to be called from elsewhere. So I created my "main" file like this:

public class ABC_Test {

    @Before
    public void setUp() {
        //steps = new WebDriverSteps(new FirefoxDriver());
        //steps = new WebDriverSteps();
    }

    @Test
    public void check() {
        CheckVal dv = new CheckVal();

        try {
            dv.checkTable("4234");
        } catch (AssertionError er) {
            System.out.println("22");
        } catch (Exception e) {
            System.out.println("23");
        } catch (Throwable t) {
            System.out.println("24");
        }

    }

}

And moved the code to do the check into:

public class CheckVal {

    @Rule
    public ErrorCollector collector = new ErrorCollector();

    public void checkTable(String value) {

        String checkMe;

        checkMe = "1234";

        System.out.println("value coming in : " + value);
        System.out.println("value to check  : " + checkMe);
        collector.checkThat("Check values match", value, is(checkMe));

    }

}

But now when I run the code, I always get a pass, even when I introduce a value to cause a fail to be generated. I cannot see what I am doing wrong here. (I know the code is messy - this is just my attempt to break things down to their simplest way to try and see my issue.)


Solution

  • The @Rule is not contained in the class under test which is run by the test runner and handles all of the annotations. Your code, at this point is just code.

    You need to change your code to move the @Rule to the class under test so the annotation gets processed:

    import org.junit.*;
    import org.junit.rules.ErrorCollector;
    
    public class ABC_Test {
        @Rule
        public ErrorCollector collector = new ErrorCollector();
    
        @Before
        public void setUp() {
           //steps = new WebDriverSteps(new FirefoxDriver());
           //steps = new WebDriverSteps();
        }
    
       @Test
       public void check() {
          CheckVal dv = new CheckVal(collector);
    
          try {
              dv.checkTable("4234");
          } catch (AssertionError er) {
            System.out.println("22");
          } catch (Exception e) {
            System.out.println("23");
          } catch (Throwable t) {
            System.out.println("24");
          }
      }
    

    }

    Then modify the resusable class to accept the ErrorCollector and process as normal:

    import org.junit.*;
    import org.junit.rules.ErrorCollector;
    import org.hamcrest.CoreMatchers;
    
    public class CheckVal {
    
    public ErrorCollector collector = null;
    
    public CheckVal(ErrorCollector collector) {
        this.collector = collector;
    }
    
    public void checkTable(String value) {
    
        String checkMe;
    
        checkMe = "1234";
    
        System.out.println("value coming in : " + value);
        System.out.println("value to check  : " + checkMe);
        collector.checkThat("Check values match", value, CoreMatchers.is(checkMe));
    
    }
    

    }

    IntelliJ (or your test runner) then reports the error as expected:

    java.lang.AssertionError: Check values match
    Expected: is "1234"
        but: was "4234"