繁体   English   中英

使用Spring 3.2和Mockito进行控制器单元测试的上下文初始化问题

[英]Context initialization issue for controller Unit testing with Spring 3.2 and Mockito

我正在尝试为我的控制器提供干净的单元测试。 该Controller具有Service作为依赖关系,而该Serviceh具有Datasource作为依赖关系。

测试如下所示:

@RunWith(SpringJUnit4ClassRunner.class)
@WebAppConfiguration
@ContextConfiguration
public class ContentActionWebServiceControllerTest {
  @Autowired
  private WebApplicationContext wac;

  private MockMvc mockMvc;

  @Autowired
  private MyService myService;

  @Test
  public void getRequestActionList() throws Exception {
    when(...)
    perform(...);
    verify(...);
  }

  @Configuration
  @ImportResource("...")
  static class MyTestConfiguration {

    @Bean
    public MyService myService() {
      return Mockito.mock(MyService.class);
    }
  }
}

而MyService就像

@Service
public class MyService {
  @Autowired
  private MyDataSource myDatasource;

  ...
}

因为MyService是Autowired属性MyDataSource,所以不会初始化上下文,因为它找不到满足MyService的@Autowired注释的任何MyDataSource类型。 但是,为什么要尝试解析此注释? 这是假的吗?

Mockito确实使用cglib创建MyService的新子类(并使用模拟方法覆盖所有方法)。

但是仍然会注入父对象的依赖项,因为这是Spring的工作方式:

如果您有一个带有某些@Autowired字段的父类,以及从该父类继承的子类,则Spring在实例化该子对象时将注入父类的@Autowired字段。 我猜这与您的情况相同。

如果您将接口用于MyService ,那么您的问题将得到解决。

如果应该将其作为单元测试(而不是集成测试),甚至不需要使用Spring,则可以使用JUnit + Mockito进行全部操作。 您可以简单地创建支持对象的@InjectMocks (通过@Mock )并将它们注入到测试对象中(通过@Mock ),而不必使用Spring上下文中的@Autowire ing依赖@InjectMocks 我相信您的代码可以简化为(在概念上)如下所示:

@RunWith(MockitoJUnitRunner.class)
public class ContentActionWebServiceControllerTest {

  @Mock
  private Service mockServiceUsedByController;

  @InjectMocks
  private YourController testee;

  @Test
  public void getRequestActionList() throws Exception {
    assertFalse(testee.getRequestActionList().isEmpty());
    // etc.
  }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM