断言复杂的spock交互

时间:2015-03-18 09:32:11

标签: unit-testing spock

真的一直在努力让这个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
    }
}

测试的想法是给控制台提供两个不良反应(“等等!”和“仍然等等!”,然后是有效回复(“是”)

然而,我无法得到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)

非常感谢任何帮助。

2 个答案:

答案 0 :(得分:1)

我认为你没有使用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);
    }
}

让我知道这是否成功。

答案 1 :(得分:1)

如果您想订购交互式模拟,那么您实际上需要单独的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
  }
}