来自模拟豆的方法无法正常工作

时间:2019-07-06 11:06:00

标签: java spring unit-testing mockito

我想为服务中的方法创建单元测试,这意味着我不想使用@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 bfalse,并且我无法使用调试器进入innerFunction()。

有什么方法可以模拟bean进行这种单元测试吗?

1 个答案:

答案 0 :(得分:0)

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

如果要对Spring Bean进行单元测试(这将从Spring Context中获取),则可能使用SpringJUnit4ClassRunner(对于JUnit4)和@MockBean(仅在Spring Boot中可用)注释在Spring Context中模拟bean进行测试。

当您创建带有模拟对象的模拟对象时,您必须说出在调用方法时该模拟对象应该做什么。例如:

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