Jmock-如何实现自动化模拟出控制台用户输入? [英] Jmock - how to automate & mock out console user input?

查看:89
本文介绍了Jmock-如何实现自动化模拟出控制台用户输入?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一些我想模拟的从main调用的功能(静态:我也已经读过-

I have some functionality that I want to mock out being called from main (static: I've read about that too - jmock mocking a static method). i recently read that JMock doesn't support the mocking of static functions. Well, the associated code (that's giving me a problem) must be called from main, and must be in the class with main...

示例源

测试代码

现在,我想确保我的主体进行了测试,以确保文件在继续之前存在.问题是,我的程序从控制台获取用户输入,所以我不知道该如何模拟?我是否只是降低了粒度级别,在过程中的每个点都指定发生了什么,以便在返回用户输入的函数中只编写一个操作?我知道编写好的测试,在运行测试时,他们不应该要求用户输入,我应该以某种方式在测试中指定它.

Right now, I want to ensure that my main has a test to make sure that the file exists before it proceeds. Problem is, I have my program getting user input from the console, so I don't know how to mock that out? Do I just go down to that level of granularity, specifying at every point along the way what happens, so that I can write about only one operation in a function that returns the user's input? I know that to write the tests well, when the tests are run, they should not ask for the user input, I should be specifying it in my tests somehow.

我认为这与以下方面有关: 如何使用JMock测试模拟方法内部的模拟方法 我对JMock不太满意...

I think it has to do with the following: How to use JMock to test mocked methods inside a mocked method I'm not that good with JMock...

推荐答案

Stefan Birkner的回答为我提供了解决此问题所需的方向.我在下面发布了用于解决此问题的代码.

Stefan Birkner's answer gave me the direction that I need to be able to solve this. I have posted the code that I used to solve this below.

已解决的测试:Birkner版本(推荐)

解决的测试:管道版本

更改了来源:

为什么:发生的事情是,使用Birkner的库,您只能读取与最初用规则实例化一样多的输入.如果要迭代地写入端点,则可以使用管道破解来做到这一点,但这并没有多大区别,您不能在函数实际运行时通过管道写入输入,因此您可以不妨使用Birkner的版本,他的@Rule更简洁.

WHY: What happens is, with Birkner's library, you can only ever read as much input as you instantiate with the rule originally. If you want to iteratively write to the endpoint, you can do this with a pipe hack, but it doesn't make much of a difference, you can't write to the input over the pipe while the function is actually running, so you might as well use Birkner's version, his @Rule is more concise.

说明:无论是在管道破解中还是在使用Birkner的代码进行测试的客户端中,多次调用以创建从System.in读取的任何对象都将导致阻塞问题,在这种情况下,第一个对象已打开与Pipe或System.in的连接,其他对象则无法.我不知道为什么这正是Birkner的代码,但是对于Pipe我认为这是因为您永远只能向对象打开1个流.请注意,如果您在第一个缓冲的读取器上调用close,然后在从测试中调用它后尝试在客户端代码中重新打开System.in,则第二次尝试打开将失败,因为在编写器侧的管道已关闭也一样

Explanation: In both the pipe hack and with Birkner's code, in the client being tested, multiple calls to create any object that reads from System.in will cause a blocking problem where, once the first object has opened a connection to the Pipe or to System.in, others can not. I don't know why this exactly is for Birkner's code, but with the Pipe I think that it's because you can only open 1 stream to the object-ever. Notice that if you call close on the first buffered reader, and then try to reopen System.in in your client code after having called it from the test, then the second attempt to open will fail because the pipe on the writer's side has been closed as well.

解决方案:解决此问题的简便方法,可能不是最好的方法,因为它需要修改实际项目的源代码,但还没有以可怕的方式进行修改(至今).因此,不要在实际项目的源代码中创建多个BufferedReader,而是创建一个缓冲的读取器,然后将相同的读取器引用传递给该类,或使其成为类的私有变量.请记住,如果必须将其声明为静态,则不应在静态上下文中对其进行初始化,因为如果这样做,则在运行测试时,将在读取器已在客户端中初始化之后调用System.setIn.因此,它将对所有readLine/无论调用如何进行轮询,就像尝试从System.in中创建多个对象一样. 注意,要使您的读取在阅读器的调用之间分开,在本例中为BufferedReader,您可以使用换行符在原始设置中将它们分开.这样,它将在被测试的客户端中的每个调用中返回您想要的内容.

Solution: Easy way to solve this, and probably not the best because it requires modifying the source of the actual project, but not in a horrendous way (yet). So instead of having in the source of the actual project multiple BufferedReader creations, create a buffered reader, and pass the same reader reference around or make it a private variable of the class. Remember that if you have to declare it static that you should not initialize it in a static context because if you do, when the tests run, System.setIn will get called AFTER the reader has been initialized in your client. So it will poll on all readLine/whatever calls, just as it will if you try to create multiple objects from System.in. Notice that to have your reads segregated between calls from your reader, in this case BufferedReader, you can use newlines to segregate them in the original setup. This way, it returns what you want in each call in the client being tested.

这篇关于Jmock-如何实现自动化模拟出控制台用户输入?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆