Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Rspec check if a method has been called without calling the method

Tags:

ruby

rspec

I am pretty new with RSpec an althought I have been reading a lot about how to check if a method has been called I cannot find a proper solution for the case I need. Sorry if this is a duplicate but couldn't find anything :S

I have an object which implements this function

def link
  paths.each do |old,new|
    FileUtils.ln_s old, new
  end
end

Several links are done based on paths (which is a hash pairing old and new files). My test for this looks like this:

context "linking files to new ones" do
  it "links a sample to the propper file" do
    @comb.link
    expect(FileUtils).to have_received(:ln_s).with("/example/path/files/old.root",
                                             "example/path/nornmfiles/new.root")
  end
end

Since I want to test that at least on of them has been called have to use the have_received method since the receive ones will fail as soon as the ln_s method gets called with different arguments. The issue is that the test fails because this is a test and I an mot going to actually create the links because the files don't exists so it fails raising an exception because the files don't exists.

How can I test this without actually having to call the method?

This call also fail as soon as a different call is made

  it "links a sample with a region subpath to the propper file" do
    expect(FileUtils).to receive(:ln_s).with("/example/path/files/pathsuff/old.root",
                                             "/example/path/normfiles/pathsuff/new.root").at_least(:once)
    @comb.link
  end

It gives this error:

RSpec::Mocks::MockExpectationError: FileUtils received :ln_s with unexpected 
arguments
   expected: ("/example/path/files/pathsuff/old.root", 
 "/example/path/normfiles/pathsuff/new.root")
   got: ("/example/path/files/old.root", 
 "/example/path/normfiles/new.root")

which is on of the other calls with different methods that can happen that can be called

like image 646
Juanpe Araque Avatar asked Dec 18 '22 02:12

Juanpe Araque


2 Answers

context "linking files to new ones" do
  it "links a sample to the propper file" do
    allow(FileUtils).to receive(:ln_s)

    @comb.link

    expect(FileUtils).to have_received(:ln_s).with(
      "/example/path/files/old.root",
      "example/path/nornmfiles/new.root",
    ).at_least(:once)
  end
end
like image 112
ndnenkov Avatar answered Dec 30 '22 07:12

ndnenkov


If you don't care about actual arguments (but rather simple number of calls)

expect(FileUtils).to receive(:ln_s).with(anything, anything).exactly(paths.length).times
@comb.link

If you do care about arguments

expect(FileUtils).to receive(:ln_s).with('foo', 'bar').ordered
expect(FileUtils).to receive(:ln_s).with('foo2', 'bar2').ordered
expect(FileUtils).to receive(:ln_s).with('foo3', 'bar3').ordered
@comb.link
like image 32
Sergio Tulentsev Avatar answered Dec 30 '22 07:12

Sergio Tulentsev