Возвращение ложных предметов от фабричной девушки - PullRequest
1 голос
/ 26 февраля 2009

Я использую Mocha и Factory_girl в приложении JRuby rails. Когда я звоню на фабрику, я хотел бы вернуть объекты с уже сделанной насмешкой Вот фрагмент кода того, что я пытаюсь сделать.

Factory.define :tweet_feed_with_tweets, :parent => :tweet_feed do |t|
  t.expects(:pull_tweets).returns([Factory.build(:status),Factory.build(:status)])
end

Поскольку я не хочу, чтобы мой модульный и функциональный тест фактически извлекал данные из API Twitter, я хочу заглушить метод, чтобы он возвращал то, что я хочу. Но это не работает. Объект возвращается без какой-либо заглушки. Есть ли способ на самом деле выполнить заглушку объекта, созданного фабричной девушкой, прежде чем он будет возвращен вам?

Ответы [ 2 ]

6 голосов
/ 26 января 2011

Обратные вызовы теперь доступны:

Factory.define :tweet_feed_with_tweets, :parent => :tweet_feed do |t|
  t.after_build do |tt|  
    tt.expects(:pull_tweets).returns([Factory.build(:status),Factory.build(:status)])
  end
end
1 голос
/ 03 марта 2009

Глядя на документацию и исходный код для factory_girl, похоже, что объект, переданный в блок (t, в вашем примере), является экземпляром Factory, а не экземпляром нужного вам объекта построить (tweet_feed_with_tweets, в вашем примере). Это означает, что установка ожидания для метода pull_tweets на t устанавливает ожидание для экземпляра Factory, а не для объекта, который будет создан при вызове Factory(:tweet_feed_with_tweets). Я думаю, это объясняет, почему ваш пример не работает так, как вы ожидаете.

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

def test_should_do_something
  tweet_feed = Factory(:tweet_feed)
  tweet_feed.expects(:pull_tweets).returns([Factory.build(:status), Factory.build(:status)])
  # test stuff here
end

Если вам это нужно в нескольких местах, вы можете извлечь его в метод: -

def test_should_do_something
  tweet_feed = build_tweet_feed_with_tweets
  # test stuff here
end

private

def build_tweet_feed_with_tweets
  tweet_feed = Factory(:tweet_feed)
  tweet_feed.expects(:pull_tweets).returns([Factory.build(:status), Factory.build(:status)])
  return tweet_feed
end

Пара других мыслей: -

  1. Я думаю, что в любом случае устанавливать ожидания в таком скрытом месте - плохая идея.
  2. Если вы собираетесь это сделать, я бы подумал, что использование stubs более уместно, чем expects.
  3. Возможно, стоит разделить метод pull_tweets (и любые подобные методы) на класс TwitterAPI. Таким образом, не все так плохо, что вам нужно настроить ожидание на TwitterAPI в тесте.

Я надеюсь, что это поможет.

...