0

这篇文章类似于:this

我有一个控制台应用程序,它需要用户输入和响应式用户输出。我正在为它编写一些单元测试以确保代码正常工作。我需要能够确保它的输出和输入是我期望的。

本质上,我有一个正在测试的主要方法,它要求提供文件或输入。在我的测试中,我使用System.setOutandSystem.setIn将它们分别设置为 PrintStream 和 InputStream 对象的 context.mock 版本。System.out.println在我必须测试程序数据的实际处理并将其结果输出到控制台时,我才关心进行了哪些调用。所以总结一下:

这是我正在测试的来源(接近的东西,我修剪了很多):http: //ideone.com/rptC0

这是我在模拟过程中的内容:http: //ideone.com/VkvqM

这是我得到的例外:ideone.com/OEOS8

正如您在我的期望中清楚地看到的那样,我明确表示我计划打印完全相同的字符串,并且我在我的期望中指定了这一点。但是例外说这是出乎意料的。我不明白...

4

1 回答 1

0

JMock 希望您使用context.checking() 然后调用被测代码来声明期望,然后调用context.assertIsSatisfied()(尽管有时如果使用适当的测试运行程序,最后一步是隐式完成的)。

您似乎context.assertIsSatisfied()在运行任何代码之前立即调用。

mn此外,您发布的代码使用了似乎未定义的变量- 这实际上是您正在运行的代码吗?还是应该mockIn改为该变量?

更新:好的,问题可能是您正在尝试模拟静态方法 - JMock 不支持这一点 - 请参阅jmock mocking a static method。请特别参阅 JMock 的作者之一 Steve Freeman 的回答。

更新 2:我会尝试这样的事情,在 @Before 设置中设置期望:

@Before
public void setMinimalMockingExpectations() throws IOException
{
    oldIn = System.in;
    oldOut = System.out;
    pipe = new PipedOutputStream();
    testIn = new PipedInputStream(pipe);
    mockOut = context.mock(PrintStream.class);
    System.setOut(mockOut);
    System.setIn(testIn);

    expectQuestion();
}

private void expectQuestion()
{
    Expectations exp = new Expectations()
    {
        {
            one(mockOut).println(main.QUESTION);
        }
    };
    context.checking(exp);

}

@After
public void reset()
{
    System.setIn(oldIn);
    System.setOut(oldOut);
}

@Test
public void fileChoiceReturnsFalse() throws IOException
{
    String FILE = "F\n";
    pipe.write(FILE.getBytes());

    assertFalse(main.promptStringOrFile());

    context.assertIsSatisfied(); // can avoid this call by using the right
                                    // test runner
}

并创建两个类似的测试来检查输入“I”和任何其他输入的行为(问题应该重复一次)。

如果您使用而不是担心字符,该promptStringOrFile()方法可能会更清晰。BufferedReader.readLine()

于 2012-04-21T20:06:16.580 回答