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

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了使用非默认构造函数和依赖注入为类创建Mockito测试相关的知识,希望对你有一定的参考价值。

我有一个使用依赖注入的类,并有一个非默认构造函数初始化其他字段。基本上这个类看起来像这样:

public class NonDefaultConstructor {
    private final String name;
    @Inject
    private SomeService service;

    public NonDefaultConstructor(ParameterObject po) {
        this.name = po.getName();
    }
}

有了这个ParameterObject

public class ParameterObject {
    private String name;

    public String getName() {
        return name;
    }
}

我想创建一个Mockito测试,注入服务SomeService的模拟和构造函数参数ParameterObject的模拟。此尝试不起作用,因为它尝试模拟尚未初始化的字段上的行为。

public NonDefaultConstructorTest {
    @Mock
    private SomeService service;
    @Mock
    private ParameterObject po;
    @InjectMocks
    private NonDefaultConstructor classUnderTest;

    @BeforeEach
    private void setup() {
        given(po.getName()).willReturn("name")
        MockitoAnnotations.initMocks(this);
    }
}

ParameterObject方法中创建setup也不起作用,因为那样需要在那里构造NonDefaultConstructor然后不会注入SomeService。我知道这可以通过使用反射手动注入字段来解决,但我更喜欢更优雅的解决方案。

答案

您可以在设置方法中“手动”创建ParameterObject,如下所示:

@BeforeEach
private void setup() {
    po = Mockito.mock(ParameterObject.class);
    given(po.getName()).willReturn("name");

    MockitoAnnotations.initMocks(this);
}

为了使这项工作,您还需要从中删除@Mock注释

@Mock
private ParameterObject po;

现在,您的ParameterObject在创建任何其他模拟之前被创建和配置,然后使用非默认构造函数注入到您的类中。

以上是关于使用非默认构造函数和依赖注入为类创建Mockito测试的主要内容,如果未能解决你的问题,请参考以下文章

为啥显式允许默认构造函数和具有 2 个或更多(非默认)参数的构造函数?

Spring 框架中 Setter 注入 和 构造器注入 方式的区别 与优劣

Angular 2 中的依赖注入在使用内联注入器和构造器注入时创建多个实例

依赖注入:在无参数构造函数中实例化具体类时你会失去啥

在Gson反序列化期间使用Dagger进行依赖注入

Spring 依赖注入原理