2016-06-18 29 views
0

我正在寻找一种方法来模拟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()) 
    } 

} 

我需要一种方法来替代这种自动连接豆与模拟/存根所以我可以在'给定'部分定义交互。

回答

1

我会在测试中创建一个本地配置并在那里覆盖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结构来简化这一点。

+0

这个可以解决我的问题,如果我使用的是Java,那么Spock的+1,bur就不是那么简单,正如你注意到的那样。我需要新的Spring Boot或新的Spock来按照我的计划进行工作。 –

相关问题