Mockito - 嘲弄遗留类构造函数

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Mockito - 嘲弄遗留类构造函数相关的知识,希望对你有一定的参考价值。

我正在为一个通过构造函数引用遗留类的类编写JUnit。遗产类是在第三方罐子里,所以我不能重构它以使生活更轻松....

这是正在测试的课程......

public MyClass {

    public String methodToTest(String param) {
        LegacyClass legacy = new LegacyClass(param);
        *..... etc ........*
    }
}

这就是我想在mockito JUnit中做的事情。

public MyClassTest {

    @Test
    public void testMethodToTest() throws Exception {
        LegacyClass legacyMock = mock(LegacyClass.class);
        when(*the LegacyClass constructor with param is called*).thenReturn(legacyMock);
        *.... etc.....*
    }
}

关于如何做到这一点的任何想法?????

答案

LegacyClass制作一个建设者:

public class LegacyClassBuilder {

    public LegacyClass build(String param) {
        return new LegacyClass(param);
    }

}

这样你的类就可以被测试,所以它创建了具有正确参数的LegacyClass

public MyClass {

    private LegacyClassBuilder builder;

    public setBuilder(LegacyClassBuilder builder) {
        this.builder = builder;
    }

    public String methodToTest(String param) {
        LegacyClass legacy = this.builder.build(param);
        ... etc
    }
}

测试看起来像这样:

// ARRANGE
LegacyClassBuilder mockBuilder = mock(LegacyClassBuilder.class);
LegacyClass mockLegacy = mock(LegacyClass.class); 
when(mockBuilder.build(anyString()).thenReturn(mockLegacy);

MyClass sut = new MyClass();
sut.setBuilder(mockBuilder);
String expectedParam = "LOLCAT";


// ACT
sut.methodToTest(expectedParam);

// ASSERT
verify(mockBuilder).build(expectedParam);

如果LegacyClass恰好是final,那么你需要为LegacyClass创建的非最终包装器,MyClass将使用。

另一答案

您可以使用PowerMockito框架:

import static org.powermock.api.mockito.PowerMockito.*;

whenNew(LegacyClass.class)
  .withParameterTypes(String.class)
  .withArguments(Matchers.any(String.class))
  .thenReturn(new MockedLegacyClass(param));

然后根据您的测试需求编写MockedLegacyClass实现。

另一答案

我相信使用Mockito模拟构造函数是不可能的。相反,我会建议以下方法:

  public MyClass {

    public String methodToTest(String param) {
     if(legacy== null){
      //when junit runs, you will get mocked object (not null), hence don't initialize 
        LegacyClass legacy = new LegacyClass(param);
      }
        *..... etc ........*
    }
}

public MyClassTest {

@InjectMock
Myclass myclass; // inject mock the real testable class
@Mock
LegacyClass legacy

@Test
public void testMethodToTest() throws Exception {    
    // when(legacy-constructor).thenReturn() ---not Required
    // instead directly mock the required methods using mocked legacy object
    when(legacy.getSomething(Mockito.any(String.class))).thenReturn(null);
        *.... etc.....*
    }
}

以上是关于Mockito - 嘲弄遗留类构造函数的主要内容,如果未能解决你的问题,请参考以下文章

使用 mockito 进行测试时,超类方法的构造函数中出现 NullPointerException

使用非默认构造函数和依赖注入为类创建Mockito测试

Junit Mockito NullPointerException for Mock 用于基于构造函数的自动装配

错误:在 null 上调用成员函数 create(),单元测试(嘲弄)

Android 逆向ART 脱壳 ( DexClassLoader 脱壳 | DexClassLoader 构造函数 | 参考 Dalvik 的 DexClassLoader 类加载流程 )(代码片段

Android 逆向ART 脱壳 ( DexClassLoader 脱壳 | DexClassLoader 构造函数 | 参考 Dalvik 的 DexClassLoader 类加载流程 )(代码片段