Search code examples
ruby-on-railsrspecruby-1.9.3machinistruby-on-rails-3.2

rails 3.2 and machinist issues


I've just upgraded to Rails 3.2.1 with Ruby 1.9.3-p0 and I'm using Machinist 2.0. Before updating a large project all my tests passed. The problem I"m having is when I create a blueprint within a 'let' call in my rspec tests and then refer to it in a before do block.

  let (:new_post) {Post.make!}

  before do
    Post.stub!(:new).and_return(new_post)
  end

This used to work, and now I get the following error:

  1) PostsController GET index assigns all posts as @posts
     Failure/Error: let (:new_post) {Post.make!}
     NoMethodError:
       undefined method `title=' for nil:NilClass
     # ./spec/support/blueprints.rb:22:in `block in <top (required)>'
     # ./spec/controllers/posts_controller_spec.rb:37:in `block (2 levels) in <top (required)>'
     # ./spec/controllers/posts_controller_spec.rb:40:in `block (2 levels) in <top (required)>'

Here is my blueprint:

require 'machinist/active_record'
Post.blueprint do
  title {"Post"}
  body {"hello world"}
end

For now my work around is to create them using instance variables within the before do block, but it would be nice to use the 'let' calls as it keeps my rspec tests cleaner.


Solution

  • Funny, I just ran across the exact same problem, although I'm on Rails 3.2.1, Machinist 2.0, and ruby 1.9.2-p290. I think there's a conflict between the execution of the Post.stub(:new) stub method and the Machinist make method, but I haven't dug into the code.

    The best solution I've come up with is:

      before do
        new_post
        Post.stub!(:new).and_return(new_post)
      end
    

    This will initialize the let (since let is lazy-loaded in rspec) before it gets to the stub method. It's hacky, but at least you (and I) can keep the let statement.