psyho / bogus

Fake library for Ruby
Other
359 stars 14 forks source link

Fake replying that it does not respond to method when it does #34

Closed allenwyma closed 10 years ago

allenwyma commented 10 years ago

I have this code:

describe Branch do
  fake(:branch)
  fake(:company)
  it "should get it's max users from it's company" do
      stub(branch).company { company }
      p (Company.new).respond_to? :max_users
      stub(company).max_users { 25 }
      expect_that { branch.max_users == 25 }
    end
end

I get this error:

Failure/Error: stub(company).max_users { 25 }
     NameError:
       #<#<Class:0x007f951f06a660>:0x007f951ee711b0 @__shadow__=#<Bogus::Shadow:0x007f951ee710c0 @calls=[], @stubs=[], @required=#<Set: {}>>> does not respond to max_users

The puts statement returns a true value, BTW, so I know that this is not a problem.

Using Zeus, Rails 4, Rspec-rail 2.14.0, latest bogus from rubygems.org.

mostlyobvious commented 10 years ago

It seems you have expectation on branch instead of company, right?

allenwyma commented 10 years ago

Both, kind of. I have a branch that belongs_to a company. The company has some values set on it that the branch will refer to. So I faked a a branch AND company. I tried to stub the branch fake so it would return the company fake, but it blows up, then.

psyho commented 10 years ago

It seems that Company#max_users is not a method (probably works on method_missing). Unfortunately there is no way for us to fake methods like that without instantiating Company behind the scenes, which in general is unacceptable.

Also, even assuming that the stubbing of company.max_users would work, there is no way that the assertion would pass. Fakes have all the same methods as real objects, but those methods do nothing, so even if real branch delegates #max_users to company, the fake one does not.

Since the test you are writing appears to be an integration test (because it integrates with ActiveRecord), it would probably be best if you used real classes here, and only stubbed the methods that contain logic. I wrote about it in another issue if you want to learn why.

allenwyma commented 10 years ago

Well, it's an attribute inside of AR, so I'm guessing that because it's an AR method, then it's not "stubbable" with a fake? If so, that's fine. I eventually got it going by, doing like what you said, stubbing the class itself.

is this the fix? Just confirm. Can we make a note in the readme?

psyho commented 10 years ago

Right, I forgot that's an AR attribute. Have you tried turning on the fake_ar_attributes configuration option?

allenwyma commented 10 years ago

Okay, will try some more with this, but it should be fine.