gpt4 book ai didi

java - 在使用 @InjectMocks 注入(inject)之前初始化模拟对象内部

转载 作者:行者123 更新时间:2023-11-30 10:19:20 24 4
gpt4 key购买 nike

我有类似的东西

private static final CustomObject ObjectA = new CustomObject();

@Mock
Foo1 foo1;

@Mock
Foo2 Foo2 = new Foo2(ObjectA);

@Mock
Foo3 foo3;

@InjectMocks
ContainerClass container;

我想在 Foo2 注入(inject)容器之前用 ObjectA 初始化它。上面的代码不起作用。

编辑:我正在尝试模拟 Foo2,但是有一个 Foo2 的内部对象,我想用一个真实的对象对其进行初始化,所以当我调用 Foo2 的方法时,这个内部对象被用来给我我需要的结果基于我在构建过程中提供的值。

最佳答案

The above code is not working.

1) @InjectMocks 使用了很多“魔法”,并不是设置被测对象模拟的最清晰和可调试的方法。
在幕后,它尝试了多种方法:构造函数注入(inject)、属性 setter 注入(inject)、字段注入(inject)。
但如果注入(inject)失败,则不会报错:

If any of the following strategy fail, then Mockito won't report failure; i.e. you will have to provide dependencies yourself.

作为替代方案,您可以显式设置被测对象的依赖关系。

2) 附带但重要的注意事项:以小写字母作为首字母命名变量。用类名命名它们是不可读的和约定俗成的。

3) 这没有意义:

@Mock
Foo2 Foo2 = new Foo2(ObjectA);

您实例化 Foo2,然后将其替换为 Mockito 模拟。
模拟 Foo2 行为但让它的 ObjectA 依赖成为一个非模拟对象并不是真正的逻辑。
通过这样做,您不会真正模拟被测对象的依赖关系,因为您的调用模式是:

object under test -> mock dep1 -> real object dep2

在这种情况下,编写集成测试(没有模拟)更有意义。

当您对 ContainerClass 进行单元测试时,您将仅测试 ContainerClass 行为。
您想要获得结果的 ObjectA 方法应该是 Foo2ObjectA 的调用,您模拟了对 Foo2 的调用 在你的测试中。
请注意,如果您模拟其调用者的方法,则无需模拟 ObjectA

这是一个例子:

public class Foo2{

private ObjectA objectA;

public Foo2(ObjectA objectA){
this.objectA = objectA;
}

public Bar callObjectA(){
return objectA.foo();
}
}

你需要在这里模拟的是callToObjectA()

@Mock
Foo1 foo1;

@Mock
Foo2 foo2;

@Test
public void myMethod(){
ContainerClass container = new ContainerClass(foo1, foo2);
Bar mockedBar = new Bar(....);
Mockito.when(foo2.callObjectA()).thenReturn(mockedBar);
// invoke the method under test
container.myMethod();
// assertions ...
}

关于java - 在使用 @InjectMocks 注入(inject)之前初始化模拟对象内部,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48672836/

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