Unit testing 未注入模拟对象

Unit testing 未注入模拟对象,unit-testing,spring-mvc,testing,junit,mockito,Unit Testing,Spring Mvc,Testing,Junit,Mockito,我尝试模拟控制器: @RestController public class SthControl { @Autowired private ObjRepo repo; @RequestMapping(value = "/dosth", method = RequestMethod.POST, produces = "application/json") public ModelMap handleSth(@RequestParam("key") Str

我尝试模拟控制器:

@RestController
public class SthControl {
    @Autowired
    private ObjRepo repo;    

    @RequestMapping(value = "/dosth", method = RequestMethod.POST, produces = "application/json")
    public ModelMap handleSth(@RequestParam("key") String key) { 
    final Logger logger = Logger.getLogger(getClass());

    logger.info("Is Mock "+ new MockUtil().isMock(repo));//return FALSE- is real object
logger.info("Key " + repo.loadByKey(key);//return NULL- always call real Method
测试用例:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("file:src/main/webapp/WEB-INF/mvc-dispatcher-servlet.xml")
@WebAppConfiguration
public class SthControlTest {
@SuppressWarnings("SpringJavaAutowiringInspection")
@Autowired
protected WebApplicationContext wac;
private MockMvc mockMvc;

@Mock
private ObjRepo repo;

@InjectMocks
@Autowired
private SthControl contr;

@Before
public void setup() {

    MockitoAnnotations.initMocks(this);
    this.mockMvc = webAppContextSetup(this.wac).build();

    BasicConfigurator.configure();
}

@Test
public void testRegister() throws Exception {

    final UUID uuid = UUID.randomUUID();
    final String keyValue = "KeyVal";

    final Logger logger = Logger.getLogger(getClass());

    repo = Mockito.mock(ObjtRepo.class);
    Mockito.when(repo.loadByKey(keyValue)).thenReturn(new Obj(uuid, keyValue, TimeUtils.currentTimeSecond(), false));
如果用这行替换@Mock注释,问题仍然存在

repo = Mockito.mock(ObjRepo.class);
ReflectionTestUtils.setField(contr, "repo", repo, ObjRepo.class);
logger.info("Obj " + repo.loadByKey(keyValue).getId());//return correct object
logger.info("Mock Is "+new MockUtil().isMock(ReflectionTestUtils.getField(contr,"repo")));//True

这里有两个问题

  • 您需要交换行this.mockMvc=webAppContextSetup(this.wac).build()
    MockitoAnnotations.initMocks(this),否则SpringWeb应用程序上下文设置完成的注入将覆盖Mockito完成的注入。始终先进行弹簧注射

  • 您需要删除行
    repo=Mockito.mock(ObjtRepo.class)testRegister
    的code>,因为此行将
    repo
    中的值替换为与您注入的值不同的值,因此在存根新值时,它不会影响
    SthControl
    的行为


你不理解我@David Wallace。手动创建的
Mock
@InjectMock
具有相同的效果。控制器始终包含“真实”类对象,无需模拟。OK。能否使用调试器检查调用
this.mockMvc=webAppContextSetup(this.wac).build()前后
SthControl
对象中的
repo
值是否相同?可能是SpringWeb应用程序上下文设置正在替换Mockito注入的值。是的,调试器显示
Mock
被Spring替换。如何修复?不幸的是,我没有删除答案的选项。我已经编辑了我的答案,以考虑到Spring问题以及多余的模拟创建。