java - 为 Factory 类创建的对象注入(inject) Mocks

标签 java spring junit mockito

我有以下类(class):

public class MyClass {        
    private Apple apple;

    public void myMethod() {
       apple = AppleFactory.createInstance(someStringVariable);
       ....
       ....
       ....
    }
}

还有测试类:

@RunWith(MockitoJUnitRunner.class)
public class MyClassTest {

        @InjectMocks 
        MyClass myClass;

        @Test
        public void myMethod(){
         ...
         ...
         ...
        }
    }

如何在 MyClass 中注入(inject) Apple 实例作为模拟?

最佳答案

你有 3 种可能性来解决这个问题:

抽象工厂:不要使用静态方法,而是使用具体工厂类:

public abstract class AppleFactory {
    public Apple createInstance(final String str);
}

public class AppleFactoryImpl implements AppleFactory {
    public Apple createInstance(final String str) { // Implementation }
}

在您的测试类中,模拟工厂:

@RunWith(MockitoJUnitRunner.class)
public class MyClassTest {

    @Mock
    private AppleFactory appleFactoryMock;

    @Mock
    private Apple appleMock;

    @InjectMocks 
    MyClass myClass;

    @Before
    public void setup() {
        when(appleFactoryMock.createInstance(Matchers.anyString()).thenReturn(appleMock);
    }

    @Test
    public void myMethod(){
     ...
     ...
     ...
    }
}

PowerMock:使用 PowerMock 创建静态方法的模拟。看my answer to a relevant question看看它是如何完成的。

可测试类:将 Apple 创建包装在 protected 方法中,并创建一个覆盖它的测试类:

public class MyClass {
   private Apple apple;

   public void myMethod() {
       apple = createApple();
       ....
       ....
       ....
   }

   protected Apple createApple() {
       return AppleFactory.createInstance(someStringVariable);
   }
}


@RunWith(MockitoJUnitRunner.class)
public class MyClassTest {

    @Mock
    private Apple appleMock;

    @InjectMocks 
    MyClass myClass;

    @Test
    public void myMethod(){
     ...
     ...
     ...
    }

    private class TestableMyClass extends MyClass {
       @Override
       public void createApple() {
          return appleMock;
       }
    }
}

当然,在你的测试类中你应该测试 TestableMyClass 而不是 MyClass

我会告诉你我对每种方法的看法:

  1. 抽象工厂方法是最好的一个 - 这是一个隐藏实现细节的清晰设计

  2. 可测试类 - 是第二个需要最少更改的选项

  3. PowerMock 选项是我最不喜欢的——你没有去寻求更好的设计,而是忽略并隐藏了你的问题。但这仍然是一个有效的选择。

关于java - 为 Factory 类创建的对象注入(inject) Mocks,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21879804/

相关文章:

java - 事务期间触发的 CDI 事件的范围

java - 如何将Spring Boot应用程序指向外部jar的logback.xml

java - maven-cobertura-plugin 不显示来源

java - 未找到测试运行程序 JUnit 4 的测试

java - 适用于 Android 的 SSH Java 库?

java - 当初始化发生在 try/catch 中时,Eclipse 给出未初始化的编译时错误

java - 使用 servlet 重定向请求并且 "setHeader"方法不起作用

javascript - 隐藏文件的文本框上传浏览按钮

java - 如何使用 ByteBuddy 向现有实例添加字段?

java - junit 3 的故障跟踪窗口不显示预期值