gpt4 book ai didi

java - 尽管创建了 2 个不同的模拟,但 InjectMocks 错误地将相同的模拟注入(inject)到 2 个相似类型的不同字段中

转载 作者:行者123 更新时间:2023-12-03 17:23:35 24 4
gpt4 key购买 nike

我有一个类有 2 个类似类型的字段。我 mock 过他们俩。但是当我使用 InjectMocks 时,注入(inject)模拟错误地将单个模拟注入(inject)到这两个字段中。
这是示例代码类:


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 被注入(inject)到 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>
我创建了这个私有(private)构造函数,专门用于使用 InjectMocks 进行测试。我不想让它公开/包私有(private),所以我不能使用字段注入(inject)。我也不想使用公共(public) setter 公开这些字段。另外,我不想让我的领域成为非最终领域。
我已经尝试将 mockito-version 升级到 3.5.10,但它仍然有这个错误。
我也尝试过让我的字段最终化并使用 setter - 然后 Injection 工作正常 - 但我不想暴露我的 setter。
我也尝试过使用构造函数注入(inject)来命名模拟 @Mock(name = "mock") ,但效果不佳。
我在这里错过了什么吗?有没有办法让它与私有(private)构造函数注入(inject)一起工作?

最佳答案

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

From what I see, PropertyAndSetterInjection takes generic types and @Mock's name attributes into account, so it works as expected for the field injection. But it doesn't work with constructors because ConstructorInjection is using only SimpleArgumentResolver which is well... very simple and doesn't have any MockCandidateFilter like property injector does.


  • There is issue with generics and mock #1056
  • @InjectMocks ignores @Mock's name of generic type #1066

  • 通常,您会:
  • 删除 @InjectMocks 并在测试的 setup 方法中构造 TestClass 实例。恕我直言,这是一种侵入性较小的方法。
  • 或者,如上所述,field 和 setter 注入(inject)工作。

  • 这两种方法都不适用于您的约束(私有(private)构造函数、无 setter 、最终字段)。
    在这种情况下,您可以借助反射来构建实例:
    @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);
    }

    关于java - 尽管创建了 2 个不同的模拟,但 InjectMocks 错误地将相同的模拟注入(inject)到 2 个相似类型的不同字段中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63889701/

    24 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com