JMock静态Mockery与本地Mockery

时间:2017-12-08 17:08:35

标签: java unit-testing jmock

我们使用JMock 2.5.1编写了大量的单元测试,并且大多数(全部?)都使用本地Mockery对象,例如:

@RunWith(JMock.class)
public class SomeTestClass {

    private Mockery context;

    @Before
    public void setUp() {
        context = new Mockery();
    }
}

我们决定升级到JMock 2.8.3,以便我们可以使用新功能,例如线程安全模拟。但是,现有的单元测试在2.8.3下运行,我得到:

Testcase: testReordering_GoingUp(com.hcs.orc.board.NameTagList2Test):   Caused an ERROR
Mockery named 'context' is null
java.lang.IllegalStateException: Mockery named 'context' is null
    at org.jmock.integration.junit4.JMock.mockeryOf(JMock.java:67)
    at org.jmock.integration.junit4.JMock.createTest(JMock.java:35)

似乎JMock 2.8.3需要静态版本的Mockery。那就是:

@RunWith(JMock.class)
public class SomeTestClass {

    public static Mockery context;

    @BeforeClass
    public static void globalSetUp() {
        context = new Mockery();
    }
}

然而,这会在测试之间的Mockery中造成流血。即使在测试之后,以前创建的模拟对象仍然存在,从而导致错误,例如:

a mock with name fullScreenFrame already exists
java.lang.IllegalArgumentException: a mock with name fullScreenFrame already exists
    at org.jmock.Mockery.mock(Mockery.java:128)
    at org.jmock.Mockery.mock(Mockery.java:120)

有没有办法从JMock 2.5.1升级到JMock 2.8.3而无需重新处理100s(1000s?)的单元测试?

注意:已编辑以反映移至JMock 2.8.3。 JMock 2.6.1不是最新的代码,尽管jmock.org已经过时并且没有维护的网站说。

3 个答案:

答案 0 :(得分:1)

尝试删除@RunWith(JMock.class)注释 - 我相信它已经被2.6.x版本之一弃用了(无论哪个引入了JUnitRuleMockery)。

除此之外,如果您愿意,可以使用注释来实例化您的模拟:

public class SomeTestClass {
    @Rule
    public JUnitRuleMockery context = new JUnitRuleMockery();

    @Mock private SomeOtherClass mockedDependency;

}

答案 1 :(得分:0)

我可以通过在Test类构造函数中创建Mockery来解决这个问题。然后它存在,JMock会查找它,但每次测试运行都会刷新它。

可能的解决方法:

@RunWith(JMock.class)
public class SomeTestClass {

    private Mockery context;

    public SomeTestClass() {
         context = new Mockery();
    }
}

答案 2 :(得分:0)

我确定的解决方法是在我的第一次传球和@ Foxsly的回答之间。它允许我移动到JMock 2.8.3,而不是重写我的Mockery声明(并移除@RunWith)。

public class SomeTestClass {

   @Rule
   public JUnitRuleMockery context = new JUnitRuleMockery();

   private SomeOtherClass fullScreenFrame;

   @Before
   public void setUp() {
       fullScreenFrame = context.mock(SomeOtherClass.class);
   }
}