andrewaylett / atunit

Run your unit tests with automatic DI and Mocking
Apache License 2.0
1 stars 0 forks source link

AtUnit doesn't work with Guice and JMock (tests that should fail pass) #13

Open GoogleCodeExporter opened 8 years ago

GoogleCodeExporter commented 8 years ago
The below test should fail, but no matter what expectation i set, it 
passes.

@RunWith(AtUnit.class)
@Container(Container.Option.GUICE)
@MockFramework(MockFramework.Option.JMOCK)
public class myTest extends MyModule{

  @Inject @Unit TestInterface testInterface;

  Mockery mockery;
  @Mock TestObject obj;

  @Test
  public void shouldFailTest() {

    context.checking(new Expectations() {{
      oneOf (obj).doTest();
    }});

    testInterface.testMethod(obj);
  }
}

public interface TestInterface {
  public void testMethod(TestObject obj);
}

public interface TestObject {
  public void doTest()
}

@Singleton
public class TestInterfaceImpl implements TestInterface {

  public void testMethod(TestObject obj){
    // no call to doTest() here!
  }
}

@Singleton
public class TestObjectImpl implements TestObject {

  public void doTest(){
    // random crap just in case
    int i = 0;
    i++;
  }
}

public class MyModule extends ServletModule {

  @Override
  protected void configureServlets() {
    bind(TestInterface.class).to(TestInterfaceImpl.class);
  }
}

The test described here should fail. I cannot get it to fail for the life 
of me. I hope it's something in my configuration, but I can't see it.

-Tristan

Original issue reported on code.google.com by lugieb...@gmail.com on 1 Sep 2009 at 1:36

GoogleCodeExporter commented 8 years ago
As a side note, if the test is rewritten as below, it still isn't failing like 
it 
should.

@RunWith(AtUnit.class)
@Container(Container.Option.GUICE)
public class myTest extends MyModule{

  @Inject @Unit TestInterface testInterface;

  Mockery mockery = new JUnit4Mockery();
  final TestObject obj = mocker.mock(TestObject.class);

  @Test
  public void shouldFailTest() {

    context.checking(new Expectations() {{
      oneOf (obj).doTest();
    }});

    testInterface.testMethod(obj);
  }
}

Original comment by lugieb...@gmail.com on 1 Sep 2009 at 1:42

GoogleCodeExporter commented 8 years ago
Sorry.. the code has a typo (the problem is still there, I just transcribed 
incorrectly). 

the test should be

mockery.checking(new Expect.....

not context.checking(new Expect....

Original comment by lugieb...@gmail.com on 1 Sep 2009 at 9:48

GoogleCodeExporter commented 8 years ago
I solved the issue for myself, but it appears that the problem lies in JMock 
(and 
perhaps the way AtUnit injects JMock mocks).

Problem has been narrowed down to:
If none of the mocked objects get called inside the execution method (i.e. 
testInterface.testMethod(obj)), the test will pass no matter what expectations 
are 
set.

To use the example above, as long as doTest() does not touch 'obj', it will 
pass any 
expectation. If doTest() calls anything on 'obj', then the expectations will be 
processed and the test will fail or pass accordingly

Original comment by lugieb...@gmail.com on 1 Sep 2009 at 10:27