2013-11-12 3 views
0

My Model:метод заглушки с другим методом

class Post < ActiveRecord::Base 
#... 
def my_method 
    {:created_at => self.created_at, :words => self.text.split.find_by{/*my_conditiond_here*/}} 
end 
#... 
end 

Контроллер:

class TasksController < ApplicationController 
#... 
def my_action 
    posts = Post.where(params[:conditions]) 
    @words = posts.map{|post| post.my_method}.flatten 
end 
#... 
end 

Но когда я пытаюсь сделать тесты для него, я получил некоторые неприятности.

it "returns words for single post" do 
    post = FactoryGirl.create :post, :text => 'any text here' 
    get :my_action 
    expect(assigns[:words]).to eq(post.my_method) 
end 

я получаю что-то вроде этого:

expected: [{:words=>["any", "text", "here"], :created_at=>2013-11-12 09:33:04 UTC}] 
     got: [{"words"=>["any", "text", "here"], "created_at"=>2013-11-12 09:33:04 UTC}] 

Более того, если я использую

expect(assigns[:words].first).to eq(post.my_method.fitst.with_indifferent_access) 

он не:

expected: {"words"=>["any", "text", "here"], "created_at"=>2013-11-12 09:33:04 UTC} 
     got: {"words"=>["any", "text", "here"], "created_at"=>2013-11-12 09:33:04 UTC} 
    (compared using ==) 

    Diff: 

Экспериментируя, я понял, что проблема в элементе .

Похоже, что это можно заглушить my_method, но я не знаю, как вернуть значение, связанное с объектом. Например, id. Или предложите, пожалуйста, лучший способ проверить my_action.

ответ

0

Я хотел бы сделать либо одно из следующих действий, но с предпочтением по отношению к второму раствору (expecations сообщение):

  1. Проверить только words массив, а не временную метку, таких как created_at.
  2. Инкапсулируйте все вызовы Post::where и #map в описательный класс/метод Singleton на Post и убедитесь, что Post получает правильное сообщение. Таким образом, вы только проверяете, что правильное сообщение передается в Post, а не тестирует Post и контроллер.

Другими словами, для решения # 2 выше, вы можете иметь это:

post.rb:

class Post 
    def self.posts_with_my_method params 
    # move code from controller here 
    end 
end 

tasks_controller.rb:

class TasksController < ApplicationController 
#... 
    def my_action 
    @words = Post.posts_with_my_method params(params) 
    end 
    #... 
end 

спецификация:

it "returns words for single post" do 
    Post.should_receive(:posts_with_my_method).and_return([:foo]) 
    get :my_action 
    expect(assigns[:words]).to eq([:foo]) 
end 
Смежные вопросы