如何使用Mockito模拟静态访问春季管理的@bean



我有一个我需要 static访问的 @Service bean:

@Service
public class MyBean implements InitializingBean {
    private static MyBean instance;
    @Override
    public void afterPropertiesSet() throws Exception {
        instance = this;
    }
    public static MyBean get() {
        return instance;
    }
    public String someMethod(String param) {
       return "some";
    }
}

用法:

@Service
public class OtherService {
    public static void makeUse() {
        MyBean myBean = MyBean.get();
    }
}

问题:当我编写用于使用stat MyBean访问的OtherService集成junit测试时,instance变量始终为null。

@RunWith(SpringRunner.class)
@SpringBootTest
public class ITest {
    @Autowired
    private OtherService service;
    @MockBean
    private MyBean myBean;
    @Before
    public void mock() {
        Mockito.when(myBean.someMethod(any()).thenReturn("testvalue");
    }
    @Test
    public void test() {
        service.makeUse(); //NullPointerException, as instance is null in MyBean
    }
}

问题:在使用这种类型的静态访问对弹簧管理的bean时如何编写集成测试?

如果要影响 @Bean -greation,请使用 @Configuration

@Configuration
public class MyConfig {
    @Bean
    public MyBean myBean() {
        return new MyBean;
    }
    @Bean
    public OtherService otherService () {
        return new OtherService(myBean());
    }
}

然后,模拟变得非常容易:

@RunWith(SpringRunner.class)
@SpringBootTest
public class ITest {
    @MockBean
    private MyBean myBean;
    @Autowired
    private OtherService service;
    @Test
    public void test() {
        // service is initialised with myBean
        ...
    }
}

当需要更多的控件时,您可以选择以下方法。有时,它提供的控制不仅仅是@mockbean。在您的测试中,您可以在调用之前轻松模拟一种方法。这是我首选的方式。

@Configuration
public class MyConfig {
    ...    
    @Bean
    public MyBean getMyBean() {
        return mock( MyBean.class);
    }
    @Bean
    public OtherService otherService () {
        return new OtherService( getMyBean());
    }
}

在应用程序中,您可以使用@AutorWired访问它并实现方法覆盖/模拟。

@RunWith(SpringRunner.class)
@SpringBootTest
public class AnotherTest {
    @Autowired
    private MyBean myBean;
    @Autowired
    private OtherService service;
    @Test
    public void test() {
        when( myBean.method( a, b)).thenReturn( something);
        service.doSomething( ....); // with myBean.method() overruled 
    }
}

相关内容

  • 没有找到相关文章

最新更新