首页 > 解决方案 > spock,在 spring bean 中模拟方法响应

问题描述

我在 Spring Boot 应用程序中有一个用 groovy (spock) 编写的集成测试。其中一个应用程序 bean 被称为Validator它具有以下方法:

public void validateIssueDates(final List<Timestamp> issueDates) {
    issueDates.forEach(issueDate -> {
        final Timestamp now = Timestamp.valueOf(LocalDateTime.now());

        if (issueDate.before(now)) {
            throw new IllegalArgumentException("Issue date is before current date");
        }
    });
}

Validator类中还有其他方法。在我的spock集成测试中,我只想模拟该特定方法的响应。通过以下方式:

Validator.validateIssueDates(_) >> null

我希望进行其他验证,但不是这个。基本上我想用 spock来实现这一点。我想消除该validateIssueDates()方法的执行

标签: springspock

解决方案


解决方案使用Spock

它是使用 [@SpringSpy][2] 完成的。
首先,我们用要包装在 spy 对象中的 spring bean 来注释字段。例如:

@SpringSpy
private CarValidator carValidator; 

然后在我们的测试中,then我们部分定义了我们希望如何覆盖来自 aa bean/spy 的方法:

then:
    3 * carValidator.validateIssueDates(_) >> null

解决方案使用Mockito(作为一种附加方法,它与 spock 解决方案无关)

我已经很容易spyMockito. spock尽管's进行了许多试验(和错误)spy,但它只是不想工作。如果我明白了,我把它贴在这里。目前,我只能分享Mockito解决方案:

@Profile("test")
@Configuration
public class BeanConfig {

    @Bean
    @Primary
    public CarValidator getCarValidatorSpy(CarValidator validator) {
        CarValidator carValidatorSpy = Mockito.spy(validator);

        Mockito.doNothing().when(carValidatorSpy).validateIssueDates(Mockito.any(CarDto.class));
        return carValidatorSpy;
    }
}

就这样。看起来相当简单。


推荐阅读