使用 spring 引导和 Spock 模拟服务

Mocking services with spring boot and Spock

我有一个服务使用另一个服务,我想模拟它。

@Service
public class CustomerService {

    @Autowired
    private CustomerRepository customerRepository;

    @Autowired
    private PatientRepository patientRepository;

    @Autowired
    private MyHelper myHelper;

    public Office createOfficeAccount(Office commonOffice) throws Exception {

      // this line calls another service via http, I want to mock it:
      Account newAccount = myHelper.createAccount(officeAccount);
      return customerRepository.save(customer);
}

这是我的测试class:

class KillBillCustomerServiceTest extends BaseSpecification {

    @Autowired
    private CustomerService customerService = Mock(CustomerService)

    @Autowired
    private PatientRepository patientRepository = Mock(PatientRepository)

    @Autowired
    private MyHelper kbHelper = Mock(MyHelper)

    def setup() {
        customerService.setPatientRepository(patientRepository)
        customerService.setMyHelper(kbHelper)
    }

    def "create new Account from Common Office"() {

        def commonOffice = createOfficeForTests()
        CustomerService customerService = new CustomerService (myHelper: kbHelper)

        when:
        kbHelper.createAccount(commonOffice) >> new Account() // want to mock it, but it is still calling the actual class to try and make the network call 
}

我的问题是如何模拟我的 MyHelper class 以便它实际上不会尝试进行真正的调用,而只是 returns 一个存根对象?

我认为您不能在 when 块中指定期望,这是根本原因。

勾选Spock interaction testing tutorial。它有一个名为 "Where to Declare Interactions" 的部分,它声明您只能在 "setup"(给定)或 "then" 块中声明期望。

这是在我的机器上运行的此类交互的简化示例:

interface Account {}

class SampleAccount implements Account {}


interface DependentService {
   Account createAccount(int someParam)
}

class DependentServiceImpl implements DependentService {

    Account createAccount(int someParam) {
       new SampleAccount()
    }
}


class MyService {

    private DependentService service

    public MyService(DependentService dependentService) {
        this.service = dependentService
}

public Account testMe(int someParam) {
    service.createAccount(someParam)
}

}

在这里你可以看到一些服务 (MyService) 被测试,它依赖于 DependantService 接口(我使用接口是因为我的示例项目的类路径中没有 CGLIB,它并不重要为了你的问题)。

这是 spock 中的测试:

class SampleSpec extends Specification {

 def "check"() {
    setup:
    def mockDependentService = Mock(DependentService)
    def mockAccount          = Mock(Account)
    1 * mockDependentService.createAccount(5) >> mockAccount
    MyService testedObject  = new MyService(mockDependentService)
    when:
    def expectedAccount = testedObject.testMe(5)
    then:
    expectedAccount == mockAccount
  }
}

如您所见,我已经在此处的给定区块中设置了我的期望值。