模拟使用Spock进行控制器测试的Spring服务
问题描述:
我正在寻找一种方法来模拟Controller中使用的服务bean,因此我只能使用MockMvc测试控制器。但是我找不到用Spock模拟替换真正豆的简单方法。一切都使用spring-boot 1.3.2版本。下面详细信息:模拟使用Spock进行控制器测试的Spring服务
我有一个下列的控制器类
@RestController
@RequestMapping(path = "/issues")
@AllArgsConstructor(onConstructor = @__(@Autowired))
public class NewsletterIssueController {
private final GetLatestNewsletterIssueService latestNewsletterIssueService;
@RequestMapping(
method = RequestMethod.GET,
path = "/latest"
)
public ResponseEntity getLatestIssue() {
Optional<NewsletterIssueDto> latestIssue = latestNewsletterIssueService.getLatestIssue();
if (latestIssue.isPresent()) {
return ResponseEntity.ok(latestIssue.get());
} else {
return ResponseEntity.notFound().build();
}
}
}
,还是集成斯波克测试这个类:
@ContextConfiguration(classes = [Application], loader = SpringApplicationContextLoader)
@WebAppConfiguration
@ActiveProfiles("test")
class NewsletterIssueControllerIntegrationSpec extends Specification {
MockMvc mockMvc
@Autowired
GetLatestNewsletterIssueService getLatestNewsletterIssueService
@Autowired
WebApplicationContext webApplicationContext
def setup() {
ConfigurableMockMvcBuilder mockMvcBuilder = MockMvcBuilders.webAppContextSetup(webApplicationContext)
mockMvc = mockMvcBuilder.build()
}
def "Should get 404 when latest issue does not exist"() {
given:
getLatestNewsletterIssueService.getLatestIssue() >> Optional.empty() // this won't work because it is real bean, not a Mock
expect:
mockMvc.perform(MockMvcRequestBuilders
.get("/issues/latest")
.contentType(JVM_BLOGGERS_V1)
.accept(JVM_BLOGGERS_V1)
).andExpect(MockMvcResultMatchers.status().isNotFound())
}
}
我需要一种方法来替代这种自动连接豆与模拟/存根所以我可以在'给定'部分定义交互。
答
我会在测试中创建一个本地配置并在那里覆盖bean。
我不知道Groovy的,但它会喜欢这种在Java中:
@ContextConfiguration(classes = NewsletterIssueControllerIntegrationSpec.Conf.class, loader = SpringApplicationContextLoader.class)
@WebAppConfiguration
@ActiveProfiles("test")
class NewsletterIssueControllerIntegrationSpec extends Specification {
@Configuration
@Import(Application.class)
public static class Conf {
@Bean
public GetLatestNewsletterIssueService getLatestNewsletterIssueService() {
return mock(GetLatestNewsletterIssueService.class);
}
}
// […]
}
警告:这种方法与工作的Mockito很好,但你可能需要斯波克的预发布版本为它工作,参考:https://github.com/spockframework/spock/pull/546
顺便说一句:Spring Boot 1.4将提供一个@MockBean
结构来简化这一点。
这个可以解决我的问题,如果我使用的是Java,那么Spock的+1,bur就不是那么简单,正如你注意到的那样。我需要新的Spring Boot或新的Spock来按照我的计划进行工作。 –