[rspec] przykrywanie metod wewnątrz innych metod

mam następującą sytuację

[code]class User
has_many :books

def first_book_title
#zwraca tytuł pierwszej książki
books.first.title
end

end

class Book
belongs_to :user
end[/code]
Książka (Book) ma pole “title”.

Teraz chce napisać najprostszy test metody first_book_title

@user.first_book_title.should be_kind_of(String)

jak mam przesłonić wywołanie books.first.title ?

Próbuje wcześniej tak:

@user = Factory.create(:user) @book = Factory.create(:book, :user_id => @user.id, :title => 'Przykładowy') @user.expects(:books).returns([@book])
Jednak test nie przechodzi i otrzymuje:

undefined method `title' for nil:NilClass

Co może być nie tak?

Jeżeli tworzysz obiekty w bazie danych, to nie potrzebujesz już stubów/mocków. Wyrzuć expects i powinno zadziałać.

Jesteś pewien? Bo coś nie bardzo chce działać.

@bober0: spróbuj definiować Factory w taki sposób:

Factory.define :user do |f| f.books { [Factory(:book)]} end
ewentualnie jeszcze możesz zdefiniować first_book w modelu User, np.

class User has_many :books has_one :first_book, :class_name => "Book", :foreign_key => "user_id", :order => "id ASC" end
i później nie potrzebujesz metody first_book_title - ale to już zależy od kontekstu w jakim będziesz tego używał.

Jeśli chodzi o podany przez Ciebie kod to wydaje mi się, że obiekt @user po wywołaniu
metody books zwraca pustą tablicę, musiałbyś go “przeładować”, żeby pobrał ponownie informacje
z DB.

Jesteś pewien? Bo coś nie bardzo chce działać.[/quote]
Tak, ponieważ stworzyłeś obiekt w bazie danych i model zadziała normalnie wyciągając sobie dane z bazy. Ja bym ot zrobił tak:

it("should return name of the first book") do book = mock_model(Book, :title => "Ruby Way") user = mock_model(User, :books => book) user.first_book_title.should == "Ruby Way" end