断言复杂的 spock 交互
Asserting complex spock interaction
一直在努力让这个 spock 测试正常工作。
被测代码:
import org.slf4j.Logger
import org.slf4j.LoggerFactory
public class UserConsole {
private static final Logger LOG = LoggerFactory.getLogger(UserConsole.class);
public boolean getConfirmationFromUser() {
writeLine("USER RESPONSE REQUIRED: yes/no");
while(true) {
final String userResponse = readLine();
if(userResponse.trim().equalsIgnoreCase("yes")){
return true;
} else if(userResponse.trim().equalsIgnoreCase("no")){
return false;
}
writeLine("Invalid input received '" + userResponse + "'. Legal values are: 'yes' or 'no'");
}
}
public String readLine() {
return System.console().readLine();
}
public void writeLine(final String text){
LOG.info(text);
}
}
还有我的测试代码:
import spock.lang.Specification
class UserConsoleTest extends Specification {
def "test getConfirmationFromUser"() {
given:
final UserConsole userConsole = Spy(UserConsole)
when:
boolean result = userConsole.getConfirmationFromUser();
then:
1 * userConsole.writeLine("USER RESPONSE REQUIRED: yes/no")
1 * userConsole.readLine() >> "blah!"
1 * userConsole.writeLine("Invalid input received 'blah!'. Legal values are: 'yes' or 'no'")
1 * userConsole.readLine() >> "still blah!"
1 * userConsole.writeLine("Invalid input received 'still blah!'. Legal values are: 'yes' or 'no'")
1 * userConsole.readLine() >> "yes"
assert result == true
}
}
测试的想法是向控制台提供两个错误响应("blah!" 和 "still blah!",然后是有效响应("yes")
但是我无法让 spock 验证交互。我经常看到这样的断言失败:
Too few invocations for:
1 * userConsole.writeLine("Invalid input received 'blah!'. Legal values are: 'yes' or 'no'") (0 invocations)
Unmatched invocations (ordered by similarity):
3 * userConsole.invokeMethod('readLine', [])
1 * userConsole.getConfirmationFromUser()
Too few invocations for:
1 * userConsole.writeLine("Invalid input received 'still blah!'. Legal values are: 'yes' or 'no'") (0 invocations)
Unmatched invocations (ordered by similarity):
3 * userConsole.invokeMethod('readLine', [])
1 * userConsole.getConfirmationFromUser()
at org.spockframework.mock.runtime.InteractionScope.verifyInteractions(InteractionScope.java:78)
at org.spockframework.mock.runtime.MockController.leaveScope(MockController.java:76)
at com.anz.axle.tooling.installer.UserConsoleTest.test GetConfirmationFromUser user initially enters invalid value(UserConsoleTest.groovy:39)
如有任何帮助,我们将不胜感激。
我认为您没有在应该使用的地方使用 writeLine 方法(根据您的测试):
import org.slf4j.Logger
import org.slf4j.LoggerFactory
public class UserConsole {
private static final Logger LOG = LoggerFactory.getLogger(UserConsole.class);
public boolean getConfirmationFromUser() {
writeLine("USER RESPONSE REQUIRED: yes/no");
while(true) {
final String userResponse = readLine();
if(userResponse.trim().equalsIgnoreCase("yes")){
return true;
} else if(userResponse.trim().equalsIgnoreCase("no")){
return false;
}
writeLine("Invalid input received '" + userResponse + "'. Legal values are: 'yes' or 'no'");
}
}
public String readLine() {
return System.console().readLine();
}
public void writeLine(final String text){
LOG.info(text);
}
}
让我知道是否成功。
如果您想订购交互模拟,那么您实际上需要单独的 then
块。如果它们都在同一个块中,则没有断言顺序。
import spock.lang.Specification
class UserConsoleTest extends Specification {
def "test getConfirmationFromUser"() {
given:
final UserConsole userConsole = Spy(UserConsole)
when:
boolean result = userConsole.getConfirmationFromUser();
then:
1 * userConsole.writeLine("USER RESPONSE REQUIRED: yes/no")
1 * userConsole.readLine() >> "blah!"
then:
1 * userConsole.writeLine("Invalid input received 'blah!'. Legal values are: 'yes' or 'no'")
1 * userConsole.readLine() >> "still blah!"
then:
1 * userConsole.writeLine("Invalid input received 'still blah!'. Legal values are: 'yes' or 'no'")
1 * userConsole.readLine() >> "yes"
then:
assert result == true
}
}
一直在努力让这个 spock 测试正常工作。
被测代码:
import org.slf4j.Logger
import org.slf4j.LoggerFactory
public class UserConsole {
private static final Logger LOG = LoggerFactory.getLogger(UserConsole.class);
public boolean getConfirmationFromUser() {
writeLine("USER RESPONSE REQUIRED: yes/no");
while(true) {
final String userResponse = readLine();
if(userResponse.trim().equalsIgnoreCase("yes")){
return true;
} else if(userResponse.trim().equalsIgnoreCase("no")){
return false;
}
writeLine("Invalid input received '" + userResponse + "'. Legal values are: 'yes' or 'no'");
}
}
public String readLine() {
return System.console().readLine();
}
public void writeLine(final String text){
LOG.info(text);
}
}
还有我的测试代码:
import spock.lang.Specification
class UserConsoleTest extends Specification {
def "test getConfirmationFromUser"() {
given:
final UserConsole userConsole = Spy(UserConsole)
when:
boolean result = userConsole.getConfirmationFromUser();
then:
1 * userConsole.writeLine("USER RESPONSE REQUIRED: yes/no")
1 * userConsole.readLine() >> "blah!"
1 * userConsole.writeLine("Invalid input received 'blah!'. Legal values are: 'yes' or 'no'")
1 * userConsole.readLine() >> "still blah!"
1 * userConsole.writeLine("Invalid input received 'still blah!'. Legal values are: 'yes' or 'no'")
1 * userConsole.readLine() >> "yes"
assert result == true
}
}
测试的想法是向控制台提供两个错误响应("blah!" 和 "still blah!",然后是有效响应("yes")
但是我无法让 spock 验证交互。我经常看到这样的断言失败:
Too few invocations for:
1 * userConsole.writeLine("Invalid input received 'blah!'. Legal values are: 'yes' or 'no'") (0 invocations)
Unmatched invocations (ordered by similarity):
3 * userConsole.invokeMethod('readLine', [])
1 * userConsole.getConfirmationFromUser()
Too few invocations for:
1 * userConsole.writeLine("Invalid input received 'still blah!'. Legal values are: 'yes' or 'no'") (0 invocations)
Unmatched invocations (ordered by similarity):
3 * userConsole.invokeMethod('readLine', [])
1 * userConsole.getConfirmationFromUser()
at org.spockframework.mock.runtime.InteractionScope.verifyInteractions(InteractionScope.java:78)
at org.spockframework.mock.runtime.MockController.leaveScope(MockController.java:76)
at com.anz.axle.tooling.installer.UserConsoleTest.test GetConfirmationFromUser user initially enters invalid value(UserConsoleTest.groovy:39)
如有任何帮助,我们将不胜感激。
我认为您没有在应该使用的地方使用 writeLine 方法(根据您的测试):
import org.slf4j.Logger
import org.slf4j.LoggerFactory
public class UserConsole {
private static final Logger LOG = LoggerFactory.getLogger(UserConsole.class);
public boolean getConfirmationFromUser() {
writeLine("USER RESPONSE REQUIRED: yes/no");
while(true) {
final String userResponse = readLine();
if(userResponse.trim().equalsIgnoreCase("yes")){
return true;
} else if(userResponse.trim().equalsIgnoreCase("no")){
return false;
}
writeLine("Invalid input received '" + userResponse + "'. Legal values are: 'yes' or 'no'");
}
}
public String readLine() {
return System.console().readLine();
}
public void writeLine(final String text){
LOG.info(text);
}
}
让我知道是否成功。
如果您想订购交互模拟,那么您实际上需要单独的 then
块。如果它们都在同一个块中,则没有断言顺序。
import spock.lang.Specification
class UserConsoleTest extends Specification {
def "test getConfirmationFromUser"() {
given:
final UserConsole userConsole = Spy(UserConsole)
when:
boolean result = userConsole.getConfirmationFromUser();
then:
1 * userConsole.writeLine("USER RESPONSE REQUIRED: yes/no")
1 * userConsole.readLine() >> "blah!"
then:
1 * userConsole.writeLine("Invalid input received 'blah!'. Legal values are: 'yes' or 'no'")
1 * userConsole.readLine() >> "still blah!"
then:
1 * userConsole.writeLine("Invalid input received 'still blah!'. Legal values are: 'yes' or 'no'")
1 * userConsole.readLine() >> "yes"
then:
assert result == true
}
}