首页 > 解决方案 > 模拟 bean 中的方法无法正常工作

问题描述

我想为服务中的方法创建单元测试,这意味着我不想使用@RunWith(SpringRunner.class)它,尽管它可以解决我的问题。

这是我的程序的样子:

    @Service
    public class MyService {
      private final SomeBean someBean;
      public MyService(SomeBean someBean) {
        this.someBean = someBean;
      }
      public boolean functionToTest() {
        boolean b = someBean.innerFunction();  // inside innerFunction() I return always true;
        return b;
        }
      }
    }

    public class SomeBean extends BaseBean {
      private String value;  // getter, setter
      public SomeBean(String value) {      //this value is always null in test
        super();
        this.value = value;
      }
      public boolean innerFunction() {
        return true;
      }
    }

    @Configuration
    public class SomeBeanConfiguration {
      @Bean
      public SomeBean getSomeBean(@Value("${prop.value}") String value) {
        return new SomeBean(value);  //can't get here while debugging test
      }
    }

这就是我想要测试的方式functionToTest()

    @RunWith(MockitoJUnitRunner.class)
    public class MyTest {

      @InjectMocks
      MyService service;

      @Mock
      SomeBean someBean;

      @Before
      public void setUp(){
        MockitoAnnotations.initMocks(this);    //although result is the same even without this set up
      }

      @Test
      public void test() {
        assertTrue(service.functionToTest());
      }
    }

测试总是失败,因为默认boolean b情况false下我无法使用调试器进入 innerFunction() 。

有没有办法为这种单元测试模拟 bean?

标签: javaspringunit-testingmockito

解决方案


您正在使用MockitoJUnitRunner这就是在测试期间未启动 Spring 配置的原因 - 未创建上下文。但这不是这里的主要问题,因为您想对您的逻辑进行单元测试。

如果您想对从 Spring Context 获取的 Spring bean 进行单元测试,您可能会使用SpringJUnit4ClassRunner(对于 JUnit4)和@MockBean(仅在 Spring Boot 中可用)注释来模拟 Spring Context 中的 bean 以进行测试。

当您使用 mockito 创建一个模拟时,您必须实际说明在调用方法时该模拟应该做什么。例如 :

Mockito.when(someBean.innerFunction()).thenReturn(true);

在这里,您说“innerFunction在我的模拟对象上调用方法时,请返回 true”。

所以你的测试可能看起来像:

@Test
public void test() {
    Mockito.when(someBean.innerFunction()).thenReturn(true);
    assertTrue(service.functionToTest());
}

此外,您不需要MockitoAnnotations.initMocks(this)@Before带注释的方法中使用,因为您已经在使用@InjectMocks注释。


推荐阅读