使用JMockit,我如何模拟一个静态工厂方法来返回一个假?

使用JMockit,我如何模拟一个静态工厂方法来返回一个假?

问题描述:

使用JMockit MockUp API,我该如何模拟静态工厂方法来返回假?使用JMockit,我如何模拟一个静态工厂方法来返回一个假?

我的问题与how do i mock the a static method that provides an instance of the class being mocked with JMockit?类似,但我的协作者的工厂方法在我的测试环境中引发了一个异常(以及正确的方法)。因此,我需要嘲笑工厂来清除有问题的操作。带有工厂方法的类是抽象的,只有一个包 - 私有构造函数。

也就是说,考虑到以下协作者,我该如何模拟collaboratorFactory()方法,使其返回一个假的协作者? (合作者是第三方的代码在这我管不着。)

public abstract class Collaborator { 
    public static Collaborator collaboratorFactory() { 
     //... some operations that throw in test env ... 
     return new CollaboratorImpl(); 
    } 

    Collaborator() { } 

    public int methodToMock() { 
     return 5; 
    } 
} 

我下测试类的作用:

public class ClassUnderTest { 
    public int getValue() { 
     return Collaborator.collaboratorFactory().methodToMock(); 
    } 
} 

我想测试“ClassUnderTest”用假的合作者说,认为回报从一些已知值“methodToMock()”我定义了我的测试类这样:当Collaborator.collaboratorFactory()抛出在我的测试环境异常

public class TestClassUnderTest { 

    static class MockCollaborator extends MockUp<Collaborator> { 
     @Mock public int methodToMock() { 
      return 124; 
     } 
    } 

    @Test 
    public void test1() throws Exception { 
     new MockCollaborator(); 
     ClassUnderTest t1 = new ClassUnderTest(); 
     assertEquals(124, t1.getValue()); 
    } 

} 

此测试失败。我真正想要做的就是将collaboratoryFactory()存放,以便它返回假冒的合作者。像下面,也许:

static class MockCollaborator extends MockUp<Collaborator> { 
     @Mock public Collaborator collaboratorFactory() { 
      // ... I don't know what to return here ... 
     } 
    } 

在collaboratorFactory的身体()方法模拟(上图),我试过返回this.getMockInstance(),但它返回null作为被嘲笑的实际方法是静态的。

FWIW,我已经能够使用Expectations API来测试我需要测试的内容,但是我觉得使用MockUp API也是可以的。

任何帮助或建议表示赞赏。

+1

您试过'return new Collaborator()'吗?或者,鉴于构造函数是'private',通过Reflection实例化它?无论如何,*正确*解决方案是有一个'@Mocked Collaborator'。 –

+0

Thanks @Rogério,我编辑了这个问题来表明Collaborator实际上是一个抽象类,所以我不能'返回新的Collaborator()'或者通过反射来实例化。当我写下这个问题时,实际的代码是一种微妙的东西,它逃脱了我。我确实想出了一个解决方案,我将发布答案。 – eakst7

+1

将'Collaborator'声明为'abstract'是没有意义的,因为它只有'private'构造函数(因此阻止了任何子类),并且因为这(只有私有构造函数)足以防止客户代码实例化类。 –

因为协作者是抽象的,所以我必须用两个MockUps,一个用于协作者,另一个用于CollaboratorImpl。抽象类中的工厂方法通过getMockedInstance()返回假实现类的实例:

static class MockCollaboratorImpl extends MockUp<CollaboratorImpl> { 
    @Mock public void $init() {}; 
    @Mock public void $clinit() {}; 
    @Mock public int methodToMock() { 
     return 124; 
    } 
} 

static class MockCollaborator extends MockUp<Collaborator> { 
    @Mock public Collaborator collaboratorFactory() { 
     return new MockCollaboratorImpl().getMockInstance(); 
    } 
}