我有一个Spring MVC应用程序。它具有Controller,Service和Dao。我想通过使用Mockito模拟DAO层来仅测试控制器和服务。
我的控制器课程:
@Controller @RequestMapping(value="/audit") public class AuditController { @Autowired AuditService auditService; ... }
我的服务班:
@Service public class AuditService { @Autowired AuditDao auditDao; .... }
我的测试班:
@RunWith(SptringJUnit4ClassRunner.class) @ContextConfiguration(locations = {"/dispatcher-servlet.xml", "spring-context.xml"}) @WebAppConfiguration public class AuditControllerTest { private MockMvc mockMvc; @Mock AuditDao auditDao; @Autowired private WebApplicationContext webApplicationContext; @Before public void setUp() { MockitAnnotations.initMocks(this); mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext).build(); } @Test public void testGetAudit() { Mockito.when(auditDao.getAudit(Mockito.any(Long.class))).thenReturn(new Audit(1L)); mockMvc.perform(get("/audit/{id}", "1")).andExpect(status().isOk()); } }
问题:它通过自动接线的控制器和服务来执行通话。但是,从服务中,DAO呼叫将转到真实的DAO,而不是模拟的DAO。
我知道DAO是自动连接到真正的Dao的,但是我不确定如何用Test中的模拟之一替换该Dao。
将Dao保留在控制器中,并对控制器使用@InjectMock可以正常工作,但是我想将Dao保留在Service中,仅测试控制器和Service,但仅模拟Dao。
我怀疑此问题与上下文(Web应用程序上下文和MockMvc上下文)有关,但是我不确定如何解决它。
任何帮助将不胜感激。提前致谢。
首先,我建议避免使用Autowired字段,并让您的类通过构造函数依赖项显式公开其依赖项
Autowired
控制器类:
@Controller @RequestMapping(value="/audit") public class AuditController { private final AuditService auditService; @Autowired public AuditController(AuditService auditService) { this.auditService = auditService } //... }
服务等级:
@Service public class AuditService { private final AuditDao auditDao; @Autowired public AuditService(AuditDao auditDao) { this.auditDao = auditDao; } //.... }
我在想一些类似的事情
@RunWith(SptringJUnit4ClassRunner.class) @ContextConfiguration(locations = {"/dispatcher-servlet.xml", "spring-context.xml"}) @WebAppConfiguration public class AuditControllerTest { private MockMvc mockMvc; @Mock AuditDao auditDao; @InjectMock AuditService auditService; @Before public void setUp() { MockitAnnotations.initMocks(this); AuditController controller = new AuditController (auditService); mockMvc = MockMvcBuilders.standaloneSetup(controller).build(); } @Test public void testGetAudit() { Mockito.when(auditDao.getAudit(Mockito.any(Long.class))).thenReturn(new Audit(1L)); mockMvc.perform(get("/audit/{id}", "1")).andExpect(status().isOk()); } }
但是不确定它在运动时是否会表现出预期。