尝试模拟来自 WebFlux 服务层的响应时出现 NullPointerException [英] NullPointerException when trying to mock response from WebFlux service layer

查看:84
本文介绍了尝试模拟来自 WebFlux 服务层的响应时出现 NullPointerException的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试为 WebFlux 应用程序的服务层中的方法编写单元测试,该方法处理另一个服务的响应,该服务进行 REST 调用并返回结果的 Mono.我已经在它自己的单元测试中使用 WebTestClient 测试嵌套服务,因此我尝试使用 Mockito 模拟它的响应,但遇到 NullPointerException 好像结果没有被模拟一样.

I'm trying to write a unit test for a method in the service layer of a WebFlux application which processes the response of another service that makes a REST call and returns a Mono of the result. I'm already testing the nested service using WebTestClient in it's own unit tests so am trying to mock out the response from it using Mockito but am encountering a NullPointerException as if the result isn't being mocked.

我对 async/reactive 模式比较陌生,所以不确定我是否做错了,或者是 Mockito 没有很好地与 react 的异步性质配合使用,但是如果它不是嵌套的服务调用,它可以正常工作被嘲笑?

I'm relatively new to async/reactive patterns so not sure if I'm doing this wrong or if it's Mockito not playing nicely with the async nature of react however it works fine if it's not a nested service call that is being mocked?

我在一个最小的例子中复制了它,表明它纯粹是对嵌套服务的模拟,它没有按预期工作,其中 NestedService.doRestCall() 返回一个 Mono<字符串>:

I've replicated it in a minimal example that show's it's purely the mocking of the nested service which isn't working as expected, where NestedService.doRestCall() returns a Mono<String>:

@Service
public class ExampleService {
  private final NestedService nestedService;

  @Autowired
  public ExampleService(final NestedService nestedService) {
    this.nestedService = nestedService;
  }

  public Mono<String> methodToTest() {
    return nestedService.doRestCall()
      .map(data -> data + "-test");
  }
}

测试:

@RunWith(SpringRunner.class)
@SpringBootTest
public class ExampleServiceTests {
  @Mock
  private NestedService nestedServiceMock;
  @InjectMocks
  private ExampleService exampleService;

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

  @Test
  public void test() {
    when(nestedServiceMock.doRestCall()).thenReturn(Mono.just("foo"));

    StepVerifier.create(exampleService.methodToTest())
      .expect("foo-test")
      .verifyComplete();
  }
}

我从 ExampleService 行中的 .map() 调用触发了以下 NullPointerException 跟踪,我也尝试使用 flatMap() 但得到相同的错误:

I get the following NullPointerException trace triggered from the .map() call in the ExampleService line, I've also tried using flatMap() but get the same error:

java.lang.NullPointerException
    at com.example.service.ExampleService.methodToTest(ExampleService.java:18)
    at com.example.service.ExampleServiceTests.test(ExampleServiceTests.java:33)

推荐答案

你初始化你的模拟两次:

You initialize your mocks twice:

  • 第一个由 spring runner
  • 然后通过 MockitoAnnotations.initMocks(this);

让我们用调试器检查 setup 方法中的变量:

Lets inspect the variables in the setup method with debugger:

initMocks 之前:

nestedServiceMock = {NestedService$MockitoMock$267376363@5567} "nestedServiceMock"
exampleService = {ExampleService@5568} 

initMocks之后:

nestedServiceMock = {NestedService$MockitoMock$267376363@5661} "nestedServiceMock"
exampleService = {ExampleService@5568} 
exampleService.nestedServiceMock = {NestedService$MockitoMock$267376363@5567} "nestedServiceMock"

您可以清楚地看到 nestedServiceMock 被重新初始化,但 exampleService 没有,并且仍然持有对旧嵌套对象的引用.

You can clearly see that the nestedServiceMock was re-initialized, but the exampleService was not, and still holds reference to the old nested object.

解决办法,去掉Spring boot注解.在这里,使用 JUnit5 清理过的版本:

To solve, get rid of Spring boot annotations. Here, cleaned-up version with JUnit5:

@ExtendWith(MockitoExtension.class)
public class ExampleServiceTest {
    @Mock
    private NestedService nestedServiceMock;
    @InjectMocks
    private ExampleService exampleService;
    
    @Test
    public void test() {
        when(nestedServiceMock.doRestCall()).thenReturn(Mono.just("foo"));

        StepVerifier.create(exampleService.methodToTest())
                .expectNext("foo-test")
                .verifyComplete();
    }
}

这篇关于尝试模拟来自 WebFlux 服务层的响应时出现 NullPointerException的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆