тестирование отношения has_one? - PullRequest
4 голосов
/ 06 октября 2010

У меня есть объект

class User < ActiveRecord::Base
  has_one :subscription
end

и у меня есть этот тест:

  it "should increment shipped count when item_shipped" do
    @user.attributes = @valid_attributes
    @user.save

    subscription = mock_model(Subscription)
    subscription.stub!(:item_shipped!)
    subscription.stub!(:user_id)
    @user.subscription = subscription

    lambda{@user.item_shipped!}.should change{@user.shipped_count}.by(1)
  end

Но я получаю ошибку:

1)
Spec::Mocks::MockExpectationError in 'User should increment shipped count when item_shipped'
Mock "Subscription_1113" received unexpected message :[]= with ("user_id", 922717357)
./spec/models/user_spec.rb:29:

Я не уверен, как это высмеивать, и не могу найти никаких ссылок на подобные вещи.

Ответы [ 3 ]

2 голосов
/ 06 октября 2010

Вместо того, чтобы издеваться над подпиской, попробуйте заглушить методы действительной подписки:

subscription = Subscription.new
subscription.stub!(:item_shipped!)
subscription.stub!(:user_id)
@user.subscription = subscription

Муки могут быть хрупкими.Любой призыв к издевательству должен быть предвиден и объявлен как ожидание.Похоже, что этому конкретному тесту в любом случае не нужна эта модель.

РЕДАКТИРОВАТЬ: Также не забудьте объявить любые возвращаемые значения, от которых зависит вызывающий класс.В вашем случае это может выглядеть так:

subscription.stub!(:item_shipped!).and_return(true)
subscription.stub!(:user_id).and_return(@user.id)

и т. Д.

Опять же, если вы не утверждаете, что должен быть вызван метод в вашей моделируемой модели, то единственное, что делает mockingвот сделай свой тест хрупким.Мок предназначен для таких вещей, как:

subscription.should_receive(:some_method).once

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

0 голосов
/ 07 октября 2010

изменить: mock_model(Subscription) на mock_model(Subscription).as_null_object

, что позволит отправлять любые сообщения объекту (при условии, что это приемлемое поведение в вашем случае)

0 голосов
/ 07 октября 2010

Настройка ассоциаций для тестов упрощается благодаря фабрикам : (не проверено)

Factory.define :subscriber, :class => User do |f|
  f.name "Moe Howard"
  f.association :subscription, :factory => :subscription
end

Factory.define :subscription, :class => Subscription do |f|
end

it "should increment shipped count when item_shipped" do
  @user = Factory.create(:subscriber)
  lambda{@user.item_shipped!}.should change{@user.shipped_count}.by(1)
end

Конечно, вы здесь не тестируете ассоциацию - вы тестируете метод item_shipped, который вы действительно хотели.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...