【问题标题】:How to Inject a service call into another method?如何将服务调用注入另一个方法?
【发布时间】:2020-10-26 17:27:32
【问题描述】:

如何在另一个方法中模拟外部调用?

我模拟了服务,但由于我没有传递模拟服务,因此该方法没有获得模拟服务。

有没有办法注入服务?


@EnableAutoConfiguration
public class MyKafkaClass(){

private final ISaveData saveData;

public void save(){
   //trying to mock the below method
   saveData.persistAddress(address);
}

}

public class MyKafkaTest(){

MyKafkaClass kafkaClass = mock(MyKafkaClass.class);
ISaveData saveData = mock(ISaveData.class);

@Test
public void saveTest(){

//Getting a null pointer exception at the below line. How do i inject ISaveData ?
doNothing().when(saveData.persistAddress(any());
kafkaClass.save();

}

}


【问题讨论】:

    标签: spring-boot junit mockito


    【解决方案1】:

    你不应该模拟 MyKafkaClass 试试

        @InjectMocks
        MyKafkaClass kafkaClass;
    
        @Mock
        ISaveData saveData;
    

    【讨论】:

      【解决方案2】:

      这段代码在很多方面都是错误的:

      1. 虽然问题与 spring 无关,但 @EnableAutoConfiguration 不应该放在常规 bean 上(例如 MyKafkaClass),因为你已经标记了 spring-boot,很可能你已经在使用 @SpringBootApplication 注释自动启用自动配置的主类(参见@SpringBootApplication 的源代码,它本身标有@EnableAutoConfiguration

      2. 由于您使用的是 final 字段,因此您可能有构造函数注入:

      public class MyKafkaClass {
        private final ISaveData saveData;
        public MyKafkaClass(ISaveData saveData) {
             this.saveData = saveData;
        }
        public void save(){
         //trying to mock the below method
         saveData.persistAddress(address);
        }
      

      这很重要,因为您的测试在概念上也是错误的:如果您正在测试 MyKafkaClass,模拟这个类没有意义,相反,您应该创建它并测试它的代码,这就是测试的目的。 ..

      所以你的测试应该是这样的:

      public class MyKafkaTest(){
      
      ISaveData saveData = mock(ISaveData.class);
      
      @Test
      public void saveTest(){
      
         // setup:
         // this is the 'object-under-test', not a mock!
         MyKafkaClass kafkaClass = new MyKafkaClass(saveData); // constructor injection is done here !
         // specify expectations for your stubs/mocks
         doNothing().when(saveData.persistAddress(any());
      
         // when: running the operation that you want to test
         kafkaClass.save();
      
         // then:
         // here you should verify the outcome of the test
      
      }
      

      现在,Mockito 库确实提供了一些方便的东西,例如 @InjectMocks@Mock(因为您应该使用特殊的 mockito 运行器 (junit4) 或扩展程序 (junit5) 运行测试,但这看起来很高级的东西在这一点上,我建议您首先了解正确单元测试背后的概念,而不管实际的工具...

      【讨论】:

        猜你喜欢
        • 2013-12-22
        • 1970-01-01
        • 1970-01-01
        • 2021-07-02
        • 2016-03-16
        • 2017-07-05
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多