简体   繁体   English

如何使用JRuby和Mocha模拟静态Java方法?

[英]How to Mock Static Java methods with JRuby and Mocha?

My goal is to unit test legacy Java code, riddled with static utility methods, using JRuby and Mocha. 我的目标是使用JRuby和Mocha对带有静态实用程序方法的遗留Java代码进行单元测试。 Is this possible? 这可能吗?

I am trying to apply similar techniques that are available in JMockit; 我正在尝试应用JMockit中可用的类似技术。 a framework leveraging proxies to change test behavior dynamically. 一个利用代理来动态更改测试行为的框架。 Purists may suggest refactoring out the static methods, but at this point, it's just not possible. 纯粹主义者可能建议重构静态方法,但目前尚不可能。

I put together two unit tests: 我整理了两个单元测试:

Test #1 - Ruby Mocking - my control. 测试#1-Ruby Mocking-我的控制。
Test #2 - Java Mocking - to see if I can accomplish the same in Java. 测试2-Java模拟-看看我是否可以在Java中完成相同的工作。

For both tests, I'm replacing the "getTax" method. 对于这两个测试,我都将替换“ getTax”方法。

Here is the code: 这是代码:

Test 1 测试1

require 'rubygems'
require 'dust'
require 'mocha'

unit_tests do

    # Test 1 - Stub out JRuby secondary class and override the "getTax" method
    # This is my "control" - I'm overriding the tax multiplier from 1.15 to 1.18.
    # It works =)
    test "RubyMocking" do
        # System Under Test
        class RInvoice 
            def initialize
                @util = RInvoiceUtil.new
            end
            def calculate
                @util.getTax * 10.0
            end
        end

        # Dependency
        class RInvoiceUtil 
            # we'll stub out this method and change the tax rate
            def getTax
                1.15
            end
        end

        invoice = RInvoice.new      
        # change the tax rate
        RInvoiceUtil.any_instance.stubs(:getTax).returns(1.18)      
        assert_equal(invoice.calculate.to_s, "11.8")
    end
end

Test 2 测试2

include Java

require 'rubygems'
require 'dust'
require 'mocha'
require 'invoice.jar'
Invoice = Java::example.Invoice
InvoiceUtil = Java::example.InvoiceUtil

unit_tests do

# Test 2 - Stub out Java class InvoiceUtil and it's *static* getTax method.
# This can be achieved via JMockit, but is it possible in Mocha?

  test "JavaMocking" do
    invoice = Invoice.new       
    # this does not work because the ruby objects are only 
    # proxies to the java objects?
    InvoiceUtil.any_instance.stubs(:getTax).returns(1.18)       
    assert_equal(invoice.calculate, 11.8)   
  end
end

Test 2 fails with: <11.5> expected but was <11.8> . 测试2失败,并出现: 预期为<11.5>但为<11.8> Ok, so I can't do that. 好的,所以我不能这样做。 Hmm. Is the reason this does not work because the ruby objects are only proxies to the java objects? 是不是因为ruby对象只是java对象的代理而不能工作的原因?

Java Source Java源码

package example;
public class Invoice {
    public double calculate() {
        return InvoiceUtil.getTax() * 10.0;
    }
}

public class InvoiceUtil {
    public static double getTax() {
        return 1.15;
    }
}

To Sum Up 总结一下

All I want to do is combine static method mocking with JRuby to leverage (1) easy scripting with (2) flexibile test isolation. 我要做的就是将静态方法模拟与JRuby结合起来,以利用(1)轻松编写脚本以及(2)灵活测试隔离。

Thanks in advance for your responses! 预先感谢您的回复!

I realize this question was asked a long time ago, but I came along a very similar problem and finally got it working. 我知道这个问题是很久以前提出的,但是我遇到了一个非常类似的问题,终于使它起作用了。 I think the problem is in your usage of any_instance... 我认为问题出在您使用any_instance ...

At least in my scenario the solution was to call stubs directly on the class containing the static method: 至少在我的方案中,解决方案是直接在包含静态方法的类上调用存根:

InvoiceUtil.stubs(:getTax).returns(1.18)

I haven't used this myself, but Ola Bini released JtestR a while ago which might be what you're looking for. 我还没有使用过它,但是Ola Bini不久前发布了JtestR ,这可能就是您想要的。 It looks like he has addressed the any_instance problem you are seeing above. 看来他已经解决了您在上面看到的any_instance问题。 I have no idea how up-to-date JtestR is, but looking at Ola's GitHub account there are some recent commits , so you could be in luck. 我不知道JtestR是什么最新版本,但是查看Ola的GitHub帐户,有一些最新的commit ,所以您可能会很幸运。 I hope this helps. 我希望这有帮助。

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

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