【问题标题】:Deep / Nested Dependency Injection in testing测试中的深度/嵌套依赖注入
【发布时间】:2016-03-07 07:47:41
【问题描述】:

我正在使用 junit、mockito 和 mockMVC 来测试 webapp 的工作。我正在与一个我无法弄清楚的注入依赖作斗争。我的webapp结构如下。

Class Controller{

    @Autowired Service searchService;

    @RequestMapping("Search")
    public returnType search(@RequestParam("parameter")String parameter){
        searchService.doSearch(parameter);
    }        
}

和服务类

Class Service{
    @Autowired Service2 service2;

    public returnType doSearch(String parameter){
        //some code
        service2.call(parameter);
    }
}

我需要测试这个控制器的搜索方法,但是 service2 当前没有运行,因此必须模拟对它的调用。我可以模拟 service2,但无法弄清楚如何在控制器的 mockMVC 实例中注入 service2 的模拟。据我所知,mockito 中的@InjectMocks 只注入一层深的模拟,而不是两层。

编辑:

我正在使用以下获取控制器的 MockMVC 实例

MockMvc controller;
controller = MockMvcBuilders.standaloneSetup(Controller);

【问题讨论】:

  • 为了模拟 Service2 ,您需要访问在单元测试期间创建的 spring 上下文。您可以通过多种方式访问​​ spring 上下文,您可以自动装配应用程序上下文,然后注入 Service 2 的模拟对象作为自动装配的主要候选对象,或者最好的方法是将其编写为 spring 的 xml,如果你有一个是用于创建测试弹簧上下文。

标签: junit mockito mockmvc


【解决方案1】:

您本质上想要做的是模拟一个 bean。

在您的情况下,您必须使用 @MockBean 注释模拟 service2 的 bean。

详情请参考this article

【讨论】:

    【解决方案2】:

    你不需要那个。

    模拟search service 就足够了,因为您掌握了需要做的事情。

    例子:

    doReturn(...).when(searchService).doSearch(any());

    在执行单元测试时,开发人员需要识别被测系统并模拟/存根所有协作者。

    因此,在这种情况下,您将为控制器和搜索服务编写单独的单元测试。

    另外,阅读 this Martin Fowler 的精彩文章 - Mocks Aren't Stubs

    【讨论】:

    • 但是我也无法测试搜索类的工作。我想在测试期间测试所有可以上线的系统。
    • 在执行单元测试时,你应该模拟/存根所有的协作者。您需要为 Search Service 编写单独的单元测试,您将在其中模拟 Service2。
    • 我通过在我的测试类中直接使用 searchService 绕过了这个问题,因为控制器只是将参数传递给它。但是,如果这种注射是可能的,请告诉我。谢谢
    猜你喜欢
    • 2015-06-22
    • 2021-11-23
    • 1970-01-01
    • 1970-01-01
    • 2018-01-27
    • 2015-05-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多