简体   繁体   English

JMock-如何模拟控制台输出

[英]JMock - how to mock console output

This post is similar to: this 这篇文章是类似于:

I have a console app that expects both user input and has responsive user output. 我有一个控制台应用程序,它既需要用户输入,又需要响应用户输出。 I am writing some unit tests for it to make sure that the code works properly. 我正在为此编写一些单元测试,以确保代码正常工作。 I need to be able to make sure that the output and input for it are what I expect them to be. 我需要确保其输出和输入与我期望的一样。

Essentially, I have a main method being tested that asks for a file or input. 本质上,我有一个正在测试的主要方法要求输入文件或输入。 In my test, I use System.setOut and System.setIn to set those to context.mock versions of PrintStream and InputStream objects respectively. 在我的测试中,我使用System.setOutSystem.setIn分别将它们设置为PrintStream对象和InputStream对象的context.mock版本。 I don't care about what System.out.println calls get made until I have to test the actual processing of the program data, when it outputs its results to the console. 我不关心要进行什么System.out.println调用,直到我必须测试程序数据的实际处理,然后才将其结果输出到控制台。 So to summarize: 总结一下:

Here's my source being tested (something close, I trimmed much out): http://ideone.com/rptC0 这是我正在测试的消息源(有些东西已经关闭,我做了很多删节 ): http : //ideone.com/rptC0

Here's what I have in my mocking procedure: http://ideone.com/VkvqM 这是我的模拟过程中的内容: http : //ideone.com/VkvqM

And here's the exception that I'm getting: ideone.com/OEOS8 这是我得到的例外: ideone.com/OEOS8

As you can clearly see in my expectations, I'm explicitly saying that I was planning to print the exact same string out, and I specified that in my expectations. 正如您在期望中可以清楚看到的那样,我明确地说是我打算打印出完全相同的字符串,并在期望中指定了该字符串。 But the exception says that it was unexpected. 但例外情况表明这是出乎意料的。 I don't understand... 我不明白

JMock expects you to declare the Expectations using context.checking() then call the code under test, then call context.assertIsSatisfied() (although sometimes the last step is done implicitly if using an appropriate test runner). JMock的希望您在使用申报的期望context.checking() 然后调用被测代码, 然后调用context.assertIsSatisfied()虽然有时最后一步是隐式进行,如果使用适当的测试运行)。

You seem to be immediately calling context.assertIsSatisfied() before running any code. 您似乎在运行任何代码之前立即调用context.assertIsSatisfied()

Also, the code you posted uses the variable mn which does not appear to be defined - is that actually the code you are running? 另外,您发布的代码使用的变量mn似乎没有定义-实际上是您正在运行的代码吗? Or should that variable be mockIn instead? 还是该变量应该mockIn

Updated : OK, the problem is probably that you are trying to mock a static method - JMock doesn't support this - see jmock mocking a static method . 更新 :好的,问题可能出在您尝试模拟静态方法-JMock不支持此方法-请参见jmock模拟静态方法 See particularly the answer from Steve Freeman, who is one of the JMock authors. 特别是来自JMock作者之一的史蒂夫·弗里曼(Steve Freeman)的答案。

Updated 2 : I would try something like this, setting an expectation in the @Before setup: 更新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
}

and create two similar tests to check behaviour for input "I" and any other input (for which the question should be repeated once). 并创建两个类似的测试来检查输入“ I”和任何其他输入(对于该问题应重复一次)的行为。

The promptStringOrFile() method is probably clearer if you use BufferedReader.readLine() rather than worrying about chars. 如果您使用BufferedReader.readLine()而不是担心字符,则promptStringOrFile()方法可能会更清晰。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM