2010-07-28 4 views
1

Недавно я недавно добавил Devise в свое первое приложение Rails3, и у меня возникли проблемы с тестированием контроллера.Тестирование двух разных ожиданий с насмешкой

Я тестирую класс User controller, который является той же моделью, которую использует Devise. Таким образом, в самом начале моей спецификации у меня есть это:

before(:each) do 
    sign_in @user = Factory.create(:user) 
end 

Теперь я могу получить тестовое прохождение без использования издевается или гася таким образом:

describe "GET edit" do 
    it "assigns the requested user as @user" do 
    user = Factory(:user) 
    get :edit, :id => user.id 
    assigns(:user).should eql(user) 
    end 
end 

Но для образовательных целей я хотел бы знать, как чтобы заставить его работать с издевательством и укусом, обычно это было бы совершенно прямолинейно, но кажется, что Devise вызывает User.find перед действием контроллера и делает сбой теста.

describe "GET edit" do 
    it "assigns the requested user as @user" do 
    user = Factory(:user) 
    User.expects(:find).with(:first, :conditions => {:id => 37}).returns(user) 
    get :edit, :id => '37' 
    assigns(:user).should be(user) 
    end 
end 

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

Любое понимание будет оценено по достоинству.

ответ

5

Можно указать несколько возвращаемых значений либо с stubs или expects так:

require 'test/unit' 
require 'mocha' 

class Foo 
end 

class FooTest < Test::Unit::TestCase 

    # This passes! 
    def test_multiple_returns_with_stubs 
    Foo.stubs(:find).returns('a').returns('b').returns('c') 

    assert_equal('a', Foo.find('z')) 
    assert_equal('b', Foo.find('y')) 
    assert_equal('c', Foo.find('x')) 
    end 

    # This passes too! 
    def test_multiple_returns_with_expects 
    Foo.expects(:find).times(1..3).returns('a').returns('b').returns('c') 

    assert_equal('a', Foo.find('z')) 
    assert_equal('b', Foo.find('y')) 
    assert_equal('c', Foo.find('x')) 
    end 
end 

Разница, по-видимому, является то, что expects должен знать, сколько раз он будет называться. Если вы ничего не укажете, он принимает once и будет жаловаться на последующие вызовы. stubs не заботясь.

+0

Большое спасибо, я пришел к аналогичному выводу. Есть ли какая-нибудь работа для того, чтобы иметь разные '.with' для разных вызовов? Я предполагаю, что другой путь - это заглушить ад из Devise ... – stuartc