【问题标题】:Mock class inside REST controller with Mockito使用 Mockito 在 REST 控制器中模拟类
【发布时间】:2015-09-07 23:08:34
【问题描述】:

我有一个 spring-boot 应用程序,它通过控制器公开一个 REST 接口。这是我的控制器的一个例子:

@RestController
public class Controller {

  @Autowired
  private Processor processor;

  @RequestMapping("/magic")
  public void handleRequest() {

    // process the POST request
    processor.process();

  }   
}

我正在尝试为此类编写单元测试,并且必须模拟处理器(因为处理需要很长时间,并且在测试控制器行为期间我试图避免此步骤)。请注意,为了这个问题,提供的示例已简化。

我正在尝试使用 mockito 框架来完成这项任务:

@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = App.class)
@WebAppConfiguration
@ActiveProfiles("test")
public class ControllerTest {

  @Autowired
  private WebApplicationContext wac;

  private MockMvc mockMvc;

  @Before
  public void setUp() throws Exception {

    this.mockMvc = MockMvcBuilders.webAppContextSetup(this.wac).build();

    Processor processor = Mockito.mock(Processor.class);
    ReflectionTestUtils.setField(Controller.class, "processor", processor);
  }

  @Test
  public void testControllerEmptyBody() throws Exception {

    this.mockMvc.perform(post("/magic")).andExpect(status().isOk());

  }
}

但是,这失败了

java.lang.IllegalArgumentException: Could not find field [processor] of type [null] on target [class org.company.Controller]
    at org.springframework.test.util.ReflectionTestUtils.setField(ReflectionTestUtils.java:112)
    ...

请有人给我一个提示,如何将这个模拟注入到我的控制器中?

【问题讨论】:

    标签: java testing junit spring-boot mockito


    【解决方案1】:

    你不应该传递一个实例来设置字段,而不是类,例如:

    ...
    
    @Autowired
    private Controller controller;
    
    ...
    
    @Before
    public void setUp() throws Exception {
    
        ...
    
        Processor processor = Mockito.mock(Processor.class);
        ReflectionTestUtils.setField(controller, "processor", processor);
    }
    

    【讨论】:

    • 有趣...我没有想到我也可以自动连接控制器。谢谢。像魅力一样工作!
    【解决方案2】:

    我认为你可以像这样直接注入模拟:

    @InjectMocks
    private ProcessorImpl processorMock;
    

    并删除这一行:

    ReflectionTestUtils.setField(Controller.class, "processor", processor);
    

    Injection of a mock object into an object to be tested declared as a field in the test does not work using Mockito?

    【讨论】:

    • 尝试使用 injectMocks 注释,但它不起作用(原始处理器被调用)。甚至尝试将其命名为与控制器内的字段名称相同...
    【解决方案3】:

    重新设计您的控制器以使用构造函数注入而不是字段注入。这使依赖关系变得明确,并使您的测试设置变得更加简单。

    【讨论】:

      【解决方案4】:
      @Before
        public void setUp() throws Exception {
      
          this.mockMvc = MockMvcBuilders.webAppContextSetup(this.wac).build();
      
          Processor processor = Mockito.mock(Processor.class);
      //This line should be added to perform mock for Processor.
         Mockito.when(processor.process()).thenReturn(<Your returned value>);
          //ReflectionTestUtils.setField(Controller.class, "processor", processor);
        }
      

      在上面将您的返回值放入“您的返回值”,并在测试中使用此值来验证您的输出。

      【讨论】:

        【解决方案5】:

        您可以删除SpringApplicationConfiguration 中的servlet 上下文类并模拟servlet 上下文。不需要注入WebApplicationContextReflectionTestUtils

        基本上,您的代码应如下所示:

        @RunWith(SpringJUnit4ClassRunner.class)
        @SpringApplicationConfiguration(classes = MockServletContext.class)
        @WebAppConfiguration
        @ActiveProfiles("test")
        public class ControllerTest {
        
          @InjectMocks
          private MyController controller;
        
          @Mock
          private Processor processor;
        
          private MockMvc mockMvc;
        
          @Before
          public void setUp() throws Exception {
            MockitoAnnotations.initMocks(this);
            this.mockMvc = MockMvcBuilders.standaloneSetup(controller).build();
        
          }
        
          @Test
          public void testControllerEmptyBody() throws Exception {
            when(proessor.process()).thenReturn(<yourValue>);    
        
            this.mockMvc.perform(post("/magic")).andExpect(status().isOk());
        
            verify(processor, times(<number of times>)).process();
          }
        }
        

        Processor 将被模拟,模拟将被注入控制器。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2020-04-02
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2020-03-30
          • 2022-12-29
          相关资源
          最近更新 更多