unit-testing - with - spock 이란
Grails/Spock:클래스 내에서 메소드가 호출되는 클래스 내에서 단일 메소드를 조롱하는 방법은 무엇입니까? (3)
Spock에 내장 된 Mocking API (객체를 부분적으로 모의하는 방법을 모르는 방법)는 사용하지 않지만 다음과 같은 트릭을 수행해야합니다.
class FooSpec extends Specification {
void "Test message processing"() {
given: "A Bulk Message"
BulkMessage bulk = new BulkMessage(messages: ['a', 'b', 'c'])
when: "Service is called"
def processMessageCount = 0
MyService.metaClass.processMessage { message -> processMessageCount++ }
def service = new MyService()
service.processBulkMessage(bulk)
then: "Each message is processed separately"
processMessageCount == bulk.messages.size()
}
}
다음을 감안할 때, processBulkMessage ()가 processMessage ()를 n 번 호출하도록 확인할 수 있도록 Spock을 사용하여 processMessage ()를 조롱하려면 어떻게해야합니까? n은 BulkMessage 내의 메시지 수입니다.
class BulkMessage {
List messages
}
class MyService {
def processBulkMessage(BulkMessage msg) {
msg.messages.each {subMsg->
processMessage(subMsg)
}
}
def processMessage(Message message) {
}
}
내 생각에 이것은 잘 설계된 해결책이 아닙니다. 테스트와 디자인이 손 잡고 진행됩니다. 더 잘 조사하기 this 이야기를 권합니다. 테스트중인 객체에서 다른 메소드가 호출되었는지 확인해야하는 경우 다른 책임으로 다른 객체로 이동해야합니다.
방법은 다음과 같습니다. 가시성이 그루브에서 어떻게 작동하는지 알기 때문에 의견에 유의하십시오.
@Grab('org.spockframework:spock-core:0.7-groovy-2.0')
@Grab('cglib:cglib-nodep:3.1')
import spock.lang.*
class MessageServiceSpec extends Specification {
def 'test'() {
given:
def service = new MessageService()
def sender = GroovyMock(MessageSender)
and:
service.sender = sender
when:
service.sendMessages(['1','2','3'])
then:
3 * sender.sendMessage(_)
}
}
class MessageSender { //package access - low level
def sendMessage(String message) {
//whatever
}
}
class MessageService {
MessageSender sender //package access - low level
def sendMessages(Iterable<String> messages) {
messages.each { m -> sender.sendMessage(m) }
}
}
Spock에서 테스트하는 Java Spring 사용자 :
constructorArgs 는 이동하지만 생성자 삽입을 사용하는 방법입니다. Spy ()는 autowired 필드를 직접 설정할 수 없습니다.
// **Java Spring**
class A {
private ARepository aRepository;
@Autowire
public A(aRepository aRepository){
this.aRepository = aRepository;
}
public String getOne(String id) {
tryStubMe(id) // STUBBED. WILL RETURN "XXX"
...
}
public String tryStubMe(String id) {
return aRepository.findOne(id)
}
public void tryStubVoid(String id) {
aRepository.findOne(id)
}
}
// **Groovy Spock**
class ATest extends Specification {
def 'lets stub that sucker' {
setup:
ARepository aRepository = Mock()
A a = Spy(A, constructorArgs: [aRepository])
when:
a.getOne()
then:
// Stub tryStubMe() on a spy
// Make it return "XXX"
// Verify it was called once
1 * a.tryStubMe("1") >> "XXX"
}
}
Spock - Spub 객체에 대한 stubbing void 메소드
// **Groovy Spock**
class ATest extends Specification {
def 'lets stub that sucker' {
setup:
ARepository aRepository = Mock()
A a = Spy(A, constructorArgs: [aRepository]) {
1 * tryStubVoid(_) >> {}
}
when:
...
then:
...
}
}