什么是@Mock注释感?

时间:2017-12-30 20:09:23

标签: spring spring-mvc mockito spring-test-mvc springmockito

我对控制器测试中的bean创建有疑问。例如,有一个这样的测试

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = {MainApplicationConfiguration.class, JPAConfig.class})
@WebAppConfiguration
public class TestMainController {

    private MockMvc mockMvc;
    @Before
    public void setUp() {
    MockitoAnnotations.initMocks(this);
    mockMvc = MockMvcBuilders.standaloneSetup(mainController).build();
    }
    @InjectMocks
    private MainController mainController;

    @Mock
    private EntryService entryService;

    @Autowired
    DBEntryRepository repository;

    @Test
    public void testEntryGet() throws Exception {

        List<DBEntry> response_data = new ArrayList<>();
        response_data.add(new DBEntry(1, 1, "STR", "DATE"));

        Mockito.when(entryService.findAllEntries())
                .thenReturn(response_data);
        MvcResult result = mockMvc.perform(get("/VT/entry/"))
                .andExpect(status().isOk()).andReturn();
        verify(entryService, times(1)).findAllEntries();
        verifyNoMoreInteractions(entryService);
    }
}

和映射在

上的控制器方法
  

/ VT /进入/

@RequestMapping(value = "/entry/", method = RequestMethod.POST)
    public ResponseEntity<Void> createEntry(@RequestBody DBEntry entry, UriComponentsBuilder ucBuilder) {
        System.out.println("Creating entry " + entry.getNum());
        try {
            entryService.saveEntry(entry);
            entryService.refreshEntryService();
        } catch (Exception e) {
            e.printStackTrace();
            return new ResponseEntity<Void>(HttpStatus.BAD_REQUEST);
        }
        HttpHeaders headers = new HttpHeaders();
        headers.setLocation(ucBuilder.path("/entry/{id}").buildAndExpand(entry.getId()).toUri());
        return new ResponseEntity<Void>(headers, HttpStatus.CREATED);
    }

EntryService使用@Service注释进行注释,MainApplicationConfiguration.class是包含@EnableWebMvc的配置,并为此EntryService扫描项目。

我想表明这个控制器确实在一个真实的应用程序中使用了这个EntryService,并且所有这些都由MainApplicationConfiguration.class耦合。

问题是:为什么带有entryService注释的@Mock在我的测试执行范围内的控制器代码中结束了?难道不仅仅是那个实例而且控制器内部应该实例化另一个bean(EntryService),为什么这个注释模拟了所有出现的那个bean(在测试范围内)?我在想,我应该编写整个其他上下文Web上下文而不是MainApplicationConfiguration.class来模拟它并替换当前定义。我很困惑为什么这个简单的注释已经做了这样的事情。

如果有人能理解这个魔法,请说出@InjectMock和@Mock之间的区别是什么?

感谢您的关注!对不起,如果我的问题非常愚蠢。我很新,它有效,但我还没有魔法。

1 个答案:

答案 0 :(得分:2)

@InjectMocks EntryService

  

Mockito将尝试仅通过构造函数注入,setter注入或属性注入来按顺序注入

因为@InjectMocks是控制器的依赖关系,EntryService将尝试在测试类中找到mainController的模拟对象并将其注入constructor injection, setter injection, or property injection。< / p>

请注意,(*m)[i][j] = x; 只会出现一个。

@Mock将字段标记为模拟对象。 @InjectMocks将模拟对象注入标记的字段,但标记的字段不是模拟。