微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

Mockito - 在被测试的异步方法中模拟一个方法

如何解决Mockito - 在被测试的异步方法中模拟一个方法

嗨,我正在尝试使用异步方法进行一些单元测试。下面是我的代码。我嘲笑 doWork 的 methodUndertest() 的第一行在执行期间返回 null 并且测试失败。我尝试了与异步相关的不同事情,但没有任何效果。我在这里错过了什么。

 public class AServiceImpl{
   @Autowired
   BService bService;

   @Async
   public CompletableFuture<String> methodUnderTest(String input){
     String s = bService.doWork(input.substring(3));
     //blah blah blah
     return CompletableFuture.completedFuture(s);
   }
}


public class AServiceTest{
  private BService bService;
  private AService aService;
  @Before
  void beforetest(){
     aService = new AServiceImpl();
     bService = mock(BService.class);
     //blah blah blah
  }

  @Test
  public void someUnittest(){
     Mockito.when(bService.doWork(any())).thenReturn("ABC");
     String s = aService.methodUnderTest("ABCDEF").get();
     Assert.assertNotNull(s);
  }
}

解决方法

此处与 @Async 无关。测试中的模拟设置没有分配给被测对象。

首先,我建议避免使用 Autowired 字段,并让您的类通过构造函数依赖项显式公开它们的依赖项

public class AServiceImpl {
    
    private final BService bService;

    @Autowired
    public AServiceImpl(BService bService) {
        this.bService = bService;
    }

    @Async
    public CompletableFuture<String> methodUnderTest(String input) {
        String s = bService.doWork(input.substring(3));

        //...

        return CompletableFuture.completedFuture(s);
    }
}

然后在测试时显式注入依赖

public class AServiceTest{
    private BService bService;
    private AService aService;

    @Before
    void beforeTest() {
        bService = mock(BService.class);
        aService = new AServiceImpl(bService); //<-- injecting mocked dependency

        //...
    }

    @Test
    public void someUnitTest(){
        // Arrange
        Mockito.when(bService.doWork(any())).thenReturn("ABC");
        // Act
        String s = aService.methodUnderTest("ABCDEF").get();
        // Assert
        Assert.assertNotNull(s);
    }
}
,

您的自动接线仅适用于生产代码。您需要在测试中手动注入模拟 BService

@Before
void beforeTest() {
    aService = new AServiceImpl();
    bService = mock(BService.class);
    aService.bService = bService;
    ...
}

您可以使用 spring 运行测试以使用 @RunWith(SpringRunner.class) (JUnit 4) 或 @ExtendWith(SpringExtension.class) (Junit 5) 注入测试依赖项。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。