Pergunta

I'm using rspec 3.0.3 and ruby 2.1.2 and just can't figure out what's going wrong. Sorry for not good code implementation (I mean that class variables), but it was the easier way to show whats going wrong.

I have 2 classes. First calling new_method of the Test class should call AnotherTest.call_method that should change @@c_var class variable.

require "rspec"

class Test
  def self.new_method
    AnotherTest.call_method
  end
end

class AnotherTest

  @@c_var = "hola"

  def self.call_method
     @@c_var = "holla from another test"
  end

  def self.c_var
    @@c_var
  end

end

And I'm writing specs for it:

describe Test do
  it "should call method from an other class" do
    Test.new_method
    expect(AnotherTest.c_var).to be_eql("holla from another test")
  end
end

And this specs is working OK. But then I'm trying to use "expect to receive call" something goes wrong

describe Test do
  it "should call method from an other class" do
    expect(AnotherTest).to receive(:call_method).and_return("holla from another test")
    Test.new_method
    expect(AnotherTest.c_var).to be_eql("holla from another test")

  end
end

Failures:

1) Test should call method from an other class
 Failure/Error: expect(AnotherTest.c_var).to be_eql("holla from another test")
   expected `"hola".eql?("holla from another test")` to return true, got false
 # ./test.rb:26:in `block (2 levels) in <top (required)>'

Seems like RSpec is making this check in something like a migration and doing a rollback after it.

It's such a strange sample, I know, but I've noticed this bug only then method of one instance of a class is calling method from the other instance and that method is trying to change something.

Foi útil?

Solução

By using expect(...).to receive(...), the original method is not being called. Rather, when it is called, it just returns whatever you passed into and_return(...) without actually executing your method.

What you probably want is and_call_original. This way, you can ensure the method is called, and still allow it to execute:

expect(AnotherTest).to receive(:call_method).and_call_original

Source: https://www.relishapp.com/rspec/rspec-mocks/v/3-0/docs/configuring-responses/calling-the-original-implementation

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top