微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

尽管创建了两个不同的模拟,但InjectMocks仍将相同的Mock错误地注入到两个类似类型的不同字段中

如何解决尽管创建了两个不同的模拟,但InjectMocks仍将相同的Mock错误地注入到两个类似类型的不同字段中

我有一个包含2个类似类型字段的类。我都嘲笑了他们两个。但是当我使用InjectMocks时,注入模拟将错误地将单个模拟注入到这两个字段中。

这是示例代码类:


import lombok.AccessLevel;
import lombok.requiredArgsConstructor;

import java.util.Set;
import java.util.function.Consumer;

@requiredArgsConstructor(access = AccessLevel.PRIVATE)
public class TestClass {

    private final Consumer<Set<Integer>> intConsumer;

    private final Consumer<Set<String>> stringConsumer;

    void PrintClass(){
        System.out.println("intConsumers: " + intConsumer);
        System.out.println("stringConsumers: " + stringConsumer);
    }
}

这是测试班:


import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnitRunner;

import java.util.Set;
import java.util.function.Consumer;

@RunWith(MockitoJUnitRunner.class)
public class TestClasstest {

    @Mock private Consumer<Set<Integer>> intConsumer;
    @Mock private Consumer<Set<String>> stringConsumer;
    @InjectMocks private TestClass testClass;

    @Test
    public void testPrint(){
        testClass.PrintClass();
    }


}

这是我运行测试时的输出:testPrint()-将intConsumer注入到intConsumer和stringConsumer中。

intConsumers: intConsumer
stringConsumers: intConsumer



Process finished with exit code 0

我正在使用Maven。

<dependency>
        <groupId>org.mockito</groupId>
        <artifactId>mockito-core</artifactId>
        <version>2.7.19</version>
</dependency>

我创建了这个私有构造函数,特别是用于使用InjectMocks进行测试。我不想将其设为public / package-private,因此无法使用字段注入。我也不想使用公共设置器公开这些字段。另外,我不想让我的字段成为非决赛。

我尝试将Mockito版本升级到3.5.10,但是它仍然存在此错误。 我也尝试过将字段定型并使用setter-然后Injection可以正常工作-但我不想公开我的setter。 我也尝试过使用构造函数注入为模拟@Mock(name =“ mock”)命名,但是效果不佳。

在这里想念什么吗?有没有办法让它与私有构造函数注入配合使用?

解决方法

这是Mockito中的一个公开错误。

从我所看到的,PropertyAndSetterInjection考虑了泛型类型和@Mock的name属性,因此它可以像预期的那样用于字段注入。但这不适用于构造函数,因为ConstructorInjection仅使用SimpleArgumentResolver,这很好……非常简单,并且没有像属性注入器那样的MockCandidateFilter。

通常,您会:

  • 放置@InjectMocks并在测试中的设置方法中构造TestClass实例。恕我直言,这是一种侵入性较小的方法。
  • 或者,如上所述,现场和二传手注射工作。

这两种方法都不适合您的约束(私有构造函数,无设置方法,最终字段)。

在这种情况下,您可以求助于反射来构建实例:

@Before
public void setUp() throws IllegalAccessException,InvocationTargetException,InstantiationException,NoSuchMethodException {
    final Constructor<TestClass> constructor = TestClass.class.getDeclaredConstructor(Consumer.class,Consumer.class);
    constructor.setAccessible(true);
    testClass = constructor.newInstance(intConsumer,stringConsumer);
}

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。