RSpec any_instance在函数中初始化的对象上存根

时间:2012-05-07 23:54:17

标签: ruby methods rspec stub

免责声明:我对RSpec和TDD一般都很陌生,所以我可能会以错误的方式解决这个问题。

我想为我的程序编写一个命令行界面,它接受一个命令并生成一个类来处理它。程序的工作方式类似于git和svn等工具;即你可以通过“srs init”初始化程序,“srs添加”以添加内容,等等。

所以我有一个类,它接受ARGV并将其传递给特定的处理程序,如下所示:

class CLI
    def run!(*arguments)
        command = arguments.shift
        case command
        when "init"
            CLI::Init.new.run!(*arguments)
        end
    end
end

我的Init处理程序将如下所示:

class CLI
    class Init
        def initialize()
        end
        def run!(*arguments)
        end
    end
end

我正在尝试为CLI类的路由功能编写测试套件。如果我使用以下内容,RSpec将失败:

describe CLI do
    it "should launch the Init handler if we pass init" do
        CLI::Init.any_instance.should_receive(:run!)
        CLI::run!(*["init"])
    end
end

然而,如果我通过直接调用Init处理程序的运行替换对CLI::run!的调用,它就会通过;即: -

describe CLI do
    it "should launch the Init handler if we pass init" do
        CLI::Init.any_instance.should_receive(:run!)
        CLI::Init.new.run!(*[])
    end
end

看起来any_instance只适用于describe块中定义/构建的实例,但我不太确定。如果有人能就我如何检查在run!函数内部构造的实例上调用类方法,或者首先测试此功能的更好方法,可以向我提供任何指导,我会非常感激。

1 个答案:

答案 0 :(得分:0)

有时解释问题会显示答案。实际上,处理程序的名称“Init”作为参数传递给describe块,更像是这样:

%w{Init}.each do |cmd|
    describe CLI do
        it "should launch the #{cmd} handler if we pass #{cmd}" do
            CLI.const_get(cmd).any_instance.should_receive(:run!)
           CLI::run!(*[cmd])
        end
    end
end

在描述问题时,我拿出循环来简化问题,但这样做了一个关键的改变 - 类的名称,Init,以大写“I”开头,而命令的名称则通过在命令行中,init以小“i”开头。

所以事实证明测试失败了,因为当我应该传递命令“init”时,我试图传递命令“Init”。

TL; DR - 原始代码 实际上有效!很抱歉打扰了。