你如何在Rspec中模拟/存根系统调用?

时间:2014-06-12 22:16:43

标签: ruby rspec

我有一个使用反引号的方法但是存根不适用它。它拉动了ls的结果:

class TestHelper
  def self.test_method
    `ls`
  end
end

rspec测试:

describe TestHelper do
  describe '.test_method' do
    subject { described_class.test_method }
    before { Kernel.stub(:`).and_return("test_dir") }
    it { expect(subject).to eql("test_dir") } 
  end
end

5 个答案:

答案 0 :(得分:8)

TestHelper收到它,然后将其委托给Kernel。所以,存根TestHelper

describe TestHelper do
  describe '.test_method' do
    subject { described_class.test_method }
    before { allow(described_class).to receive(:`).and_return("test_dir") }
    it { is_expected.to eql("test_dir") } 
  end
end

答案 1 :(得分:4)

在方法中包装ls,并将该方法存根。

def ls
  `ls`
end

保留此方法以返回您想要的任何内容。您不需要测试系统调用。

答案 2 :(得分:3)

由于您的TestHelper类继承自Object,因此它也有一个反引号方法,因为"[t]he Kernel module is included by class Object, so its methods are available in every Ruby object."

如果你想测试TestHelper.test_method调用带有'ls'的{​​{3}}方法作为参数,而不是实际返回的内容(我假设这是因为&#39} ;你的所有方法都做到了:它没有在任何其他操作中使用从ls返回的值。如果确实如此,那么在其他操作中使用该值将有意义)你可以放弃测试一个stubed out方法的值,并测试在你自己的TestHelper类上调用预期的反引号方法。但是,如果你仍然想要使用存根方法调用,我已经在下面对这两种方法进行了潜在的测试:

describe TestHelper do
  describe '.test_method' do
    describe 'called methods' do
      it 'calls the `ls` command' do
        expect(described_class).to receive(:`).with('ls')
        described_class.test_method
      end
    end

    describe 'result' do
      let(:test_method) { described_class.test_method }
      let(:directories) { 'test_dir' }

      before do
        allow(described_class).to receive(:`).with('ls').and_return(directories)
      end

      it 'equals the expected directories' do
        expect(test_method).to eq(directories)
      end
    end
  end
end

答案 3 :(得分:1)

您可以存储模块的任何实例:

allow_any_instance_of(Module).to receive(:`).and_return("test_dir")

答案 4 :(得分:0)

我不知道为什么stub不适用于反引号方法。 (我必须看一下RSpec来源,我现在没有时间。)但是你可以手动将其存根:

module Kernel
  def `(*args); "test_dir"; end
end
相关问题