gpt4 book ai didi

java - 使用@InjectMocks 将@Autowired 字段替换为模拟实现

转载 作者:行者123 更新时间:2023-11-30 06:52:41 25 4
gpt4 key购买 nike

我想用我专门为测试创建的类的模拟实现替换我的 spring boot 应用程序中服务的 Autowiring 类。

我选择创建这个模拟实现是因为此类的行为太复杂而无法使用 mockito 进行模拟,因为它本身需要多个其他模拟。

我不知道如何将这个模拟的实现注入(inject)到服务中。

这是这种情况的一个最小示例:

@Service
public class ServiceIWantToTestImpl implements ServiceIWantToTest{

@Autowired
ComplicatedDependency complicatedDependency;

@Override
public void methodUsingDependency(){
String string = complicatedDependency.doSomething();
System.out.println(string);
}

}


public class MockComplicatedDependency implements ComplicatedDepencency{

public MockComplicatedDependency(...){
// Inject other mocked objects into this mock
}

public String doSomthing(){
// This would be a mocked version of this function for testing
return "test";
}

}

@RunWith(MockitoJUnitRunner.class)
public class TestingTheService(){
@InjectMock
private static ServiceIWantToTest serviceIWantToTest = new ServiceIWantToTestImpl();

@Mock
ComplicatedDependency mockComplicatedDependency;

@BeforeClass
public static void init(){
mockComplicatedDependency = new MockComplicatedDependency(...);
}

@Test
public void testAttempt(){
serviceIWantToTest.methodUsingDependency(); // This method calls complicatedDependency.doSomething() which does not run the mocked version in MockComplicatedDependency which I wanted to inject, and would always return null instead of the "test" string I put in this example.
}

}

最佳答案

是否必须使用 Mockito 注释来为被测类设置依赖项?

如果这不是主要约束,为什么不进行简单的设置并在 ServiceIWantToTestImpl 中引入构造函数或 setter? ComplicatedDependency 的类字段并将测试设置中的依赖项直接设置为您喜欢的 ComplicatedDependency 的任何含义,例如:

@Service
public class ServiceIWantToTestImpl implements ServiceIWantToTest {

@Autowired
ComplicatedDependency complicatedDependency;

public ServiceIWantToTestImpl() {

}

public ServiceIWantToTestImpl(ComplicatedDependency complicatedDependency) {
this.complicatedDependency = complicatedDependency;
}

@Override
public void methodUsingDependency(){
String string = complicatedDependency.doSomething();
System.out.println(string);
}
}

public class TestingTheService {

private static ServiceIWantToTestImpl serviceIWantToTest;

@BeforeClass
public static void init(){
serviceIWantToTest = new ServiceIWantToTestImpl(new MockComplicatedDependency());
}

@Test
public void testAttempt() {
serviceIWantToTest.methodUsingDependency();
}

}

这是一种方式。

要让它与 Mockito 一起工作,您可以像这样使用@Spy 而不是@Mock:

@RunWith(MockitoJUnitRunner.class)
public class TestingTheService {

@InjectMocks
private static ServiceIWantToTestImpl serviceIWantToTest = new ServiceIWantToTestImpl();

@Spy
private static ComplicatedDependency complicatedDependency = new MockComplicatedDependency();

@BeforeClass
public static void init() {

}

@Test
public void testAttempt() {
serviceIWantToTest.methodUsingDependency();
}

}

虽然这有点hack。我强烈建议您阅读 @Spy 注释的 JavaDoc,并确保它的预期用途是您测试真正需要的。

关于java - 使用@InjectMocks 将@Autowired 字段替换为模拟实现,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38516105/

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