Witam, potrzebuje przetestować pewną funkcjonalność która zależy od tego czy scope jest dodana. Model user jest w aplikacji, natomiast testuje engine, stąd takie kombinacje, próbowałem coś takiego
it 'do something' do
User.class(lub instance)_eval do
scope :some_users, lambda { where("users.email LIKE '%foo%' ")}
end
tutaj test ...
class << User
remove_method :some_users
end
# reload User model
Object.send(:remove_const, 'User')
load 'user.rb'
end
Test uruchomiony oddzielnie zawsze przechodzi. Natomiast testy przechodzą lub nie, losowo.
Jakieś porady jak to dodać i usunąć poprawnie ? Czy lepiej używać class_eval czy instance_eval ?
instance_eval jeśli jest to wyłącznie dla danej instancji i nie będziesz tego potrzebował w innym miejscu
zamień lambdę na definicję metody klasowej (def self.some_users), łatwiej ci będzie dostać się do unscoped zakresu i może nawet ustawić jakąś osobną zmienną mówiącą czy dany scope został zaaplikowany.
Ale po co miałbym się dostawać do zakresu unscoped ? Ja nie chce sprawdzać czy scope został dodany, tylko chce sprawdzić pewną funkcjonalność, której zwrócone dane, zależą od tego czy scope jest czy go nie ma, działać musi ze scopem czy bez.
Konkretnie chodzi mi o ogranicznienie dostępu do nowej funkcjonalności w aplikacji na produkcji, do pewnej grupy użytkowników (zdefiniowanej w modelu User np za pomocą scope), przykładowo userzy o mailu z wybranej domeny. Może po prostu źle sie za to zabieram ?
Funkcjonalność jest “rozwalona” po paru miejscach, w widoku, w dwóch kontrolerach, jest też mailer, odpowiada za nią engine.
ps, możesz rozwinąć punkt 1, bo nie do końca rozumiem
Nie rozumiem do końca co chcesz uzyskać, ale wydaje mi się, że używanie instance_eval w ten sposób, to proszenie się o problemy.
Czy mógłbyś rozwinąć trochę opis sytuacji? Tzn. gdzie co się znajduje i jak to dokładnie ma działać? Jakiś pseudo code z tych miejsc, w których tego używasz (widoki, kontrolery, model) mile widziany.
Jest to system odznaczeń zaimplementowany w engine. Testowo tylko pewna grupa użytkowników powinna widzieć kto dostał nowe odznaczenia jak otrzymywać je za wybrane zasługi itp.
Wszystko działa ok, tylko testy wywalają się gdy próbuje symulować dodanie tej scope do modelu.
Po prostu go dodaje w kodzie aplikacji (nie engine). Ale chciałbym mieć uniwersalne testy dla przypadków gdy on jest lub gdy go nie ma. bo docelowo go nie będzie.
Chyba że to przekombinowane i lepiej dać testy i scope a potem po udostępnieniu ficzera dla wszystkich poprawić dostosować testy ?
doszedłem do tego że testy losowo wywalały się z powodu tego kodu
Object.send(:remove_const, 'User')
load 'user.rb'
Prawdopodobnie dlatego że jest użyty engine. Usunięcie powyższego kodu ze speców pomogło. Natomiast w testach funkcjonalnych zgodnie z radą zmockowałem tą metode. Tak że tylko w modelu jest testowana pełnie.