使用 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
}
}
如您所见,我已经在此处的给定区块中设置了我的期望值。
我有一个服务使用另一个服务,我想模拟它。
@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
}
}
如您所见,我已经在此处的给定区块中设置了我的期望值。