Создание тестовых контроллеров для встраиваемых моделей Mongoid - PullRequest
0 голосов
/ 01 декабря 2011

Я работаю над приложением Rails 3, которое позволяет пользователям следить за фильмами, добавляя их в свою очередь, чтобы они были уведомлены о премьере фильмов.

Поскольку я использую Mongoid,Я структурировал его так, что когда пользователь добавляет фильм в свою очередь, он создает внедренный документ adds, а также увеличивает add_counter на модели Movie на 1.

Я смог заставить свои спецификации пройти, подтверждая, что это поведение работает на уровне модели, но теперь, когда я собираю контроллер, я не могу получить прощальный ответ.Я всюду искал решение, и даже после того, как уснул на нем и вернулся к нему, я не смог понять, что я делаю неправильно.

Вот моя спецификация контроллера:

# spec/controllers/adds_controller_spec.rb

require 'spec_helper'

describe AddsController do

  before(:each) do
    @user = Factory(:user)
    @movie = Factory(:movie)
  end

  describe '#create' do

    context 'given valid params' do

      before(:each) do
        sign_in @user
      end

      it "creates a new add" do
        add_count @user.adds.count
        post :create, :movie_id => @movie.id
        @user.adds.count.should == add_count + 1
      end

    end
  end
end

Вот мой контроллер:

# controllers/adds_controller.rb    

class AddsController < ApplicationController
  before_filter :authenticate_user!

  def create
    @movie = Movie.find(params[:movie_id])
    @user = current_user
    @user.add_to_queue!(@movie)

    respond_to do |format|
      format.js
    end
  end
end

А вот мои модели:

# models/movie.rb

class Movie
include Mongoid::Document
include Mongoid::Timestamps
include Mongoid::MultiParameterAttributes

field :add_counter, :type => Integer, :default => 0

# models/user.rb

class User
include Mongoid::Document
include Mongoid::Timestamps
include Mongoid::MultiParameterAttributes

embeds_many :adds

def add_to_queue!(movie)
  if already_added?(movie) == false
    adds.create!(:movie_id => movie.id)
    movie.add_counter += 1
  end
end

def already_added?(movie)
  adds.where(:movie_id => movie.id).exists?
end

# models/add.rb

class Add
include Mongoid::Document
include Mongoid::Timestamps
include Mongoid::MultiParameterAttributes

field :movie_id, :type => String
key   :movie_id

embedded_in :user

Наконец, вот отзыв от Rspec, когда я запускаю тест контроллера:

Failures:

  1) AddsController#create given valid params creates a new add
     Failure/Error: @user.adds.count.should == 1
       expected: 1
            got: 0 (using ==)
     # ./spec/controllers/adds_controller_spec.rb:25:in `block (4 levels) in <top (required)>'

1 Ответ

1 голос
/ 10 декабря 2011

Этот код слишком сложен.Я бы избавился от класса Add.Концепция добавления должна моделироваться не объектом, а отношением.

Создайте два класса (упрощенно):

movie.rb

class Movie
    include Mongoid::Document
    has_and_belongs_to_many :user_queues, :class_name => "User", :inverse_of => :movie_queue
end

user.rb

class User
    include Mongoid::Document
    has_and_belongs_to_many :movie_queue, :class_name => "Movie", :inverse_of => :user_queues
end

Синтаксис здесь может быть не точным, но относитесь к ним как к массивам, и вы будете золотыми.

...