测试使用System.console()的Groovy类
我有一个groovy脚本,使用readline方法通过
java.io.console对象向用户提出一些问题.另外,我用它来询问密码(用于设置HTTPS).我如何使用Spock对这段代码进行单元测试?目前它抱怨该对象是
Java最终对象,无法进行测试.显然,我不是第一个尝试这个的人,所以我想我会问.
代码草图看起来像: class MyClass { def cons MyClass() { cons = System.console() } def getInput = { prompt,defValue -> def input = (cons.readLine(prompt).trim()?:defValue)?.toString() def inputTest = input?.toLowerCase() input } } 我希望单元测试能够测试是否可以返回一些模拟响应,并且可以返回默认值.注意:这是简化的,所以我可以弄清楚如何进行单元测试,getInput方法中还有更多的代码需要测试,但是一旦我清除了这个障碍应该没问题. 由akhikhl编辑的每回答 interface TestConsole { String readLine(String fmt,Object ... args) String readLine() char[] readPassword(String fmt,Object ... args) char[] readPassword() } 然后我尝试了这样的测试: def "Verify get input method mocking works"() { def consoleMock = GroovyMock(TestConsole) 1 * consoleMock.readLine(_) >> 'validResponse' inputMethods = new MyClass() inputMethods.cons = consoleMock when: def testResult = inputMethods.getInput('testPrompt','testDefaultValue') then: testResult == 'validResponse' } 我选择不改变构造函数,因为我不想改变我的实际代码只是为了测试它.幸运的是,Groovy让我用一个’def’定义控制台,所以我做的工作正常. 问题是以上不起作用!!!我无法抗拒 – 这不是逻辑! Spock在某个地方的GroovyMockMetaClass中获得了“迷失”.如果我在代码中更改了一行,而在测试中更改了一行就可以了. 代码更改: From: def input = (cons.readLine(prompt).trim()?:defValue)?.toString() To: (add the null param) def input = (cons.readLine(prompt,null).trim()?:defValue)?.toString() 测试变更: From: 1 * consoleMock.readLine(_) >> 'validResponse' To: (again,add a null param) 1 * consoleMock.readLine(_,null) >> 'validResponse' 然后测试终于起作用了.这是Spock中的一个错误,还是我只是在左外野?我不介意需要做任何可能在测试工具中需要的东西,但必须修改代码才能使这项工作真的非常糟糕. 解决方法
你是对的:因为Console类是final,所以无法扩展.因此,解决方案应朝另一个方向发展:
>创建新类MockConsole,不是从Console继承,但具有相同的方法. MyClass(cons = null){ 更新201312272156 我玩了一点spock.模拟“readLine(String fmt,Object … args)”的问题似乎特定于varargs(或者最后arg是一个列表,这与groovy相同).我设法将问题减少到以下场景: 定义一个接口: interface IConsole { String readLine(String fmt,Object ... args) } 定义测试: class TestInputMethods extends Specification { def 'test console input'() { setup: def consoleMock = GroovyMock(IConsole) 1 * consoleMock.readLine(_) >> 'validResponse' when: // here we get exception "wrong number of arguments": def testResult = consoleMock.readLine('testPrompt') then: testResult == 'validResponse' } } 这个测试变体失败,异常“参数数量错误”.特别是,spock认为readLine接受2个参数而忽略了第二个参数是vararg的事实.证明:如果我们从IConsole.readLine中删除“Object … args”,则测试成功完成. 以下是针对此(希望是临时的)问题的解决方法:将对readLine的调用更改为: def testResult = consoleMock.readLine('testPrompt',[] as Object[]) 然后测试成功完成. 我也尝试了针对spock 1.0-groovy-2.0-SNAPSHOT的相同代码 – 问题是一样的. 更新201312280030 varargs的问题解决了!非常感谢@charlesg,他回答了我的相关问题:Spock: mock a method with varargs 解决方案如下:用Mock替换GroovyMock,然后正确解释varargs. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |