gpt4 book ai didi

java - 使用 FakeRequest 时模拟内部依赖

转载 作者:行者123 更新时间:2023-11-30 07:34:14 26 4
gpt4 key购买 nike

我正在使用 Play Framework 2.3.x,并且我想测试对特定路由(例如“/”)的调用是否通过调用特定方法来结束注入(inject)的组件。

例如,经典 Controller :

public class MyController extends Controller {
@Inject private MyService myService;

public Result index() { myService.foo(); }
...

 

服务实现注入(inject)了我想要模拟的另一个服务:

@Service
public class MyServiceImpl implements MyService {
@Inject private ExternalService externalService;

public void foo() { externalService.call(...); }
...

我想模拟 call() 并检索其参数以检查它们是否包含预期的内容。

@RunWith(SpringJUnit4ClassRunner.class)
@Profile("test")
@ContextConfiguration(classes = ApiConfiguration.class)
public class MyControllerTest {
@Test public void test() {
Result result = routeAndCall(new FakeRequest("GET", "/"), 10000);
// here, I expect to retrieve and test the args of a mocked externalService.call
}
}

我使用 FakeRequest 调用路由(并且不注入(inject) Controller 并手动调用方法),以便考虑一些注释并拥有 http 上下文(在某些区域使用)。

我正在使用 Mockito,我尝试了几种组合,但无法注入(inject)我的模拟(总是调用真正的方法),例如:

@Before public void initMocks() {
MockitoAnnotations.initMocks(this);
}

@Mock ExternalService externalService;
...
when(externalService.call().then(invocation -> {
Object[] args = invocation.getArguments();

这可能吗?你有什么想法吗?

我偶然发现了https://github.com/sgri/spring-reinject/这似乎适合(未测试),但我不想使用另一个项目来完成我认为不需要的事情。

谢谢。

最佳答案

问题原因是你的 DI 注入(inject)器对你的模拟一无所知

@Mock ExternalService externalService;

Spring 上下文 bean 集和 Mockito 模拟集最初没有任何交集。

要解决此问题,您应该将模拟定义为 Spring 配置的一部分。例如。像这样

@RunWith(SpringJUnit4ClassRunner.class)
@Profile("test")
@ContextConfiguration(classes = {ApiConfiguration.class, MyControllerTest.MyConfig.class})
public class MyControllerTest {

@Autowired
ExternalService externalService;

@Test public void test() {
...
}

@Configuration
public static class MyConfig {
@Bean
@Primary // it tells Spring DI to select your mock instead of your real ExternalService impl
public ExternalService mockExternalService() {
return Mockito.mock(ExternalService.class);
}
}
}

使用此代码,您

  1. 从 MyControllerTest.MyConfig 为 Spring DI 定义其他 bean 源;
  2. mockExternalService 方法中手动创建你的 bean-mock;
  3. 定义此模拟是ExternalService 的主要实现,并且...
  4. ...让 Spring 了解您的 bean-mock 并在系统中的任何位置 Autowiring 该模拟。

在此之后

@Autowired 
ExternalService externalService;

您可以像往常一样在测试中使用模拟。例如。定义此行为

Mockito.doThrow(NullPointerException.class).when(externalService).call(...);

关于java - 使用 FakeRequest 时模拟内部依赖,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35635888/

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