RubyRedGrapefruit
RubyRedGrapefruit

Reputation: 12224

Rails 3.2 RSpec test confusion with FactoryGirl

I am building a simple test to display product for a user. My spec looks like this:

require 'spec_helper'

describe "Show Products" do
  it "Displays a user's products" do
    product = Factory(:product)
    visit products_path
    page.should have_content("ABC1")
  end
end

and my factory for product looks like this:

FactoryGirl.define do
  factory :product do
    sequence(:identifier, 1000) {|n| "ABC#{n}" }
  end
end

I have a simple view:

<table id="products">
  <thead>
<th>Product ID</th>
  </thead>
  <tbody>
    <% for product in @products %>
      <tr>
        <td><%= @product.identifier %></td>
      </tr>
    <% end %>
  </tbody>
</table>

The error I'm getting is that there is no such thing as @products. Well, yeah. And that's my question. Since my factory is defined as "product", and there is a sequence in it, how do I put the values from "product" into a variable called "products".

I am basically confused by the FactoryGirl syntax above. How can I have multiple products generated on that one line, yet the factory name has to match the model?

Upvotes: 1

Views: 286

Answers (1)

Justin Leitgeb
Justin Leitgeb

Reputation: 1107

The instance variable @products is most likely assigned in the index action of your ProductsController, or it probably should be defined there if it's not.

Generally what happens in request specs is that you use a Factory to create an object that is persisted in the database, and the controller subsequently retrieves those records and assigns them to an instance variable that is made available to the view. Since it looks like you're rendering an index, I would expect to see something like this in your controller:

class ProductsController < ApplicationController::Base
  def index
    @products = Product.all
  end
end

This instance variable will be available to the view when it is rendered.

Also, it looks like you have a typo in your view. In the iterator you have:

for product in @products
  # do something with product
end

This is going to iterate over every one of the products, and make the variable 'product' available within the block. Instead, you're using @product in the block, which seems to be a typo.

Upvotes: 1

Related Questions