1

免责声明:总的来说,我对 RSpec 和 TDD 很陌生,所以我可能会以完全错误的方式解决这个问题。

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

所以我有一个类,它接受 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

但是,如果我将调用替换为CLI::run!直接调用 Init 处理程序的运行,它就会通过;IE:-

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!函数内部构造的实例上是否调用了类方法,或者首先测试此功能的更好方法,我将不胜感激。

4

1 回答 1

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——原始代码确实有效!抱歉打扰了。

于 2012-05-08T09:08:45.740 回答