2

I have some code in a Rails model that does this:

has_one :plan
validates_presence_of :plan

And used to do this:

after_initialize :set_plan

def set_plan
  self.plan ||= FreePlan.new
end

and now does:

def plan
  super || (self.plan = FreePlan.new)
end

Now, however, this test fails:

it { is_expected.to validate_presence_of(:plan) }

The new code is nicer in that it doesn't always have to look up a plan object in the DB for every instantiation of this object, but I'm curious what the test is doing in terms of the object under test and its lifecycle.

David N. Welton
  • 1,875
  • 18
  • 33

1 Answers1

1

Here's what is happening:

with the older code, after_initialize is called, and the value is automatically populated. But it's possible to subsequently set plan to nil and then try and save it.

With the new code, valid? is going to call the plan method and therefore populate it, so that when the test suite inspects errors, it's not going to find any for plan.

Perhaps the best course of action is to remove the line from the test suite and add one ensuring that plan is never nil.

David N. Welton
  • 1,875
  • 18
  • 33