Das erste Jahr der neuen Absolventen ist fast vorbei. Während ich Spocks Framework benutzte, stieß ich auf verschiedene Arten, Mockito und Spock zu verspotten, also machte ich ein Memorandum und teilte es ähnlichen Leuten mit. Es wäre besser, eine Instanz in der tatsächlichen Situation zu erstellen, ohne den hier beschriebenen Code zu verspotten, aber es ist nur ein Beispiel ...
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-web'
compileOnly 'org.projectlombok:lombok'
annotationProcessor 'org.projectlombok:lombok'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
// https://mvnrepository.com/artifact/org.spockframework/spock-core
testCompile group: 'org.spockframework', name: 'spock-core', version: '1.3-groovy-2.5'
// https://mvnrepository.com/artifact/org.codehaus.groovy/groovy-all
compile group: 'org.codehaus.groovy', name: 'groovy-all', version: '2.5.6', ext: 'pom'
}
Es wird auf GitHub veröffentlicht.
Mockito
Verwenden Sie when --then Return
, um den vom Mock zurückgegebenen Wert festzulegen. Da spockComponent1Factory das Ziel der Injektion ist, wird "initMocks" mit "setup" und die Anmerkung "InjectMocks" hinzugefügt. Es scheint, dass Sie die Anzahl überprüfen können, indem Sie "wahr" in den Teil "verifizieren" schreiben, aber es fühlt sich sehr seltsam an ...
SpockComponent1FactoryTest.groovy
@InjectMocks
SpockComponent1Factory spockComponent1Factory
@Mock
SpockComponent2Factory spockComponent2Factory
@Mock
SpockComponent2 spockComponent2
@Mock
SpockComponent3 spockComponent3
@Mock
SpockComponent4 spockComponent4
def setup() {
initMocks(this)
}
def "GetValueFromSpockComponent4 -Überprüfen Sie die Anzahl der Anrufe"() {
given:
when(spockComponent2Factory.create(any(Integer.class))).thenReturn(spockComponent2)
when(spockComponent2.getSpockComponent3()).thenReturn(spockComponent3)
when(spockComponent3.getSpockComponent4()).thenReturn(spockComponent4)
when:
spockComponent1Factory.getValueFromSpockComponent4(0)
then:
verify(spockComponent2Factory, times(1)).create(any(Integer.class)) || true
}
Verwenden Sie RETURN_DEEP_STUBS
, um verschachtelte Instanzen zu verspotten. Durch Umschreiben des obigen Tests kann wie folgt geschrieben werden.
SpockComponent1FactoryTestAlt.groovy
@InjectMocks
SpockComponent1Factory spockComponent1Factory
@Mock
SpockComponent2Factory spockComponent2Factory
@Mock(answer = Answers.RETURNS_DEEP_STUBS)
SpockComponent2 spockComponent2
@Mock
SpockComponent4 spockComponent4
def setup() {
initMocks(this)
}
def "getValueFromSpockComponent -Unterbrechung der Anrufzählungsprüfung"() {
given:
when(spockComponent2Factory.create(any(Integer.class))).thenReturn(spockComponent2)
when(spockComponent2.getSpockComponent3().getSpockComponent4()).thenReturn(spockComponent4)
when:
spockComponent1Factory.getValueFromSpockComponent4(0)
then:
verify(spockComponent2Factory, times(1)).create(any(Integer.class)) || true
}
Spock Ein ähnlicher in Spock geschriebener Test sieht folgendermaßen aus: Wenn Sie die Anzahl der Ausführungen überprüfen möchten, scheint der Test nicht bestanden zu werden, es sei denn, Sie verspotten und stubben gleichzeitig in der "dann" -Klausel. Übrigens, wenn Sie in Spock das in "setup" festgelegte Verhalten mit einzelnen Testfällen überschreiben möchten, müssen Sie dies anscheinend in der "then" -Klausel tun. (Referenz: Stackoverflow-Official Document)
SpockComponent1FactoryTestSpock.groovy
SpockComponent1Factory spockComponent1Factory
SpockComponent2Factory spockComponent2Factory
SpockComponent2 spockComponent2
SpockComponent3 spockComponent3
SpockComponent4 spockComponent4
def setup() {
spockComponent2Factory = Mock(SpockComponent2Factory.class)
spockComponent2 = Mock(SpockComponent2.class)
spockComponent3 = Mock(SpockComponent3.class)
spockComponent4 = Mock(SpockComponent4.class)
}
def "GetValueFromSpockComponent4 -Anrufzählungsprüfung fehlgeschlagen"() {
given:
spockComponent3.getSpockComponent4() >> spockComponent4
spockComponent2.getSpockComponent3() >> spockComponent3
spockComponent2Factory.create(_ as Integer) >> spockComponent2
when:
spockComponent1Factory = new SpockComponent1Factory(spockComponent2Factory)
spockComponent1Factory.getValueFromSpockComponent4(0)
then:
1 * spockComponent2Factory.create(_ as Integer)
}
def "GetValueFromSpockComponent4 -Erfolgreiche Überprüfung der Anrufanzahl"() {
given:
spockComponent3.getSpockComponent4() >> spockComponent4
spockComponent2.getSpockComponent3() >> spockComponent3
when:
spockComponent1Factory = new SpockComponent1Factory(spockComponent2Factory)
spockComponent1Factory.getValueFromSpockComponent4(0)
then:
1 * spockComponent2Factory.create(_ as Integer) >> spockComponent2
}
Spock braucht auch etwas Einfallsreichtum, um verschachtelte Instanzen zu verspotten. Weniger als.
SpockComponent1FactoryTestSpockAlt.groovy
SpockComponent1Factory spockComponent1Factory
SpockComponent2Factory spockComponent2Factory
SpockComponent2 spockComponent2
SpockComponent4 spockComponent4
def setup() {
spockComponent2Factory = Mock(SpockComponent2Factory.class)
spockComponent2 = Mock(SpockComponent2.class)
spockComponent4 = Mock(SpockComponent4.class)
}
def "GetValueFromSpockComponent4 -Unterbrechung der Anrufzählungsprüfung"() {
given:
spockComponent2.getSpockComponent3() >> {
Mock(SpockComponent3.class) {
getSpockComponent4() >> spockComponent4
}
}
when:
spockComponent1Factory = new SpockComponent1Factory(spockComponent2Factory)
spockComponent1Factory.getValueFromSpockComponent4(0)
then:
1 * spockComponent2Factory.create(_ as Integer) >> spockComponent2
}
Im Implementierungscode wird null direkt in die Methode eingefügt, die das Argument String verwendet.
SpockComponent1Factory.java
public void nullArgumentMethodCall() {
spockComponent2Factory.nullArgumentMethodCalled(null);
}
Mockito Als ich versuchte, mit "any ()" zu prüfen, konnte es nicht überprüft werden, also habe ich "nullable ()" verwendet.
SpockComponent1FactoryTest.groovy
@InjectMocks
SpockComponent1Factory spockComponent1Factory
@Mock
SpockComponent2Factory spockComponent2Factory
@Mock
SpockComponent2 spockComponent2
@Mock
SpockComponent3 spockComponent3
@Mock
SpockComponent4 spockComponent4
def setup() {
initMocks(this)
}
def "NullArgumentMethodCall -Anrufzählungsprüfung fehlgeschlagen"() {
when:
spockComponent1Factory.nullArgumentMethodCall()
then:
verify(spockComponent2Factory, times(1)).nullArgumentMethodCalled(any(String.class)) || true
}
def "NullArgumentMethodCall -Erfolgreiche Überprüfung der Anrufanzahl"() {
when:
spockComponent1Factory.nullArgumentMethodCall()
then:
verify(spockComponent2Factory, times(1)).nullArgumentMethodCalled(nullable(String.class)) || true
}
Spock Die Spock-Seite funktionierte ohne Probleme.
SpockComponent1FactoryTestSpock.groovy
SpockComponent1Factory spockComponent1Factory
SpockComponent2Factory spockComponent2Factory
SpockComponent2 spockComponent2
SpockComponent3 spockComponent3
SpockComponent4 spockComponent4
def setup() {
spockComponent2Factory = Mock(SpockComponent2Factory.class)
spockComponent2 = Mock(SpockComponent2.class)
spockComponent3 = Mock(SpockComponent3.class)
spockComponent4 = Mock(SpockComponent4.class)
}
def "NullArgumentMethodCall -Überprüfen Sie die Anzahl der Anrufe"() {
when:
spockComponent1Factory = new SpockComponent1Factory(spockComponent2Factory)
spockComponent1Factory.nullArgumentMethodCall()
then:
spockComponent2Factory.nullArgumentMethodCalled(_ as String)
}
}
Wie eingangs erwähnt, kann es möglich sein, den Testcode durch das Erstellen einer Instanz besser lesbar zu machen als durch Verspotten. Daher scheint es besser, ihn während des Denkens zu schreiben (auch als Gebot an sich selbst).
Recommended Posts