我遵循TDD方法來構建我們的應用程序,並創建一大堆服務對象,嚴格保持模型的數據管理。在服務測試中剔除ActiveRecord模型
我建立的許多服務都與模型接口。舉個例子MakePrintsForRunner:
class MakePrintsForRunner
def initialize(runner)
@runner = runner
end
def from_run_report(run_report)
run_report.photos.each do |photo|
Print.create(photo: photo, subject: @runner)
end
end
end
我很欣賞的創建方法也可以說是被抽象成打印模式,但讓我們保持它作爲是現在。
現在,在MakePrintsForRunner的規範中,我非常希望避免包含spec_helper,因爲我希望我的服務規範超快。
相反,我踩滅打印類是這樣的:
describe RunnerPhotos do
let(:runner) { double }
let(:photo_1) { double(id: 1) }
let(:photo_2) { double(id: 2) }
let(:run_report) { double(photos: [photo_1, photo_2]) }
before(:each) do
@service = RunnerPhotos.new(runner)
end
describe "#create_print_from_run_report(run_report)" do
before(:each) do
class Print; end
allow(Print).to receive(:create)
@service.create_print_from_run_report(run_report)
end
it "creates a print for every run report photo associating it with the runners" do
expect(Print).to have_received(:create).with(photo: photo_1, subject: runner)
expect(Print).to have_received(:create).with(photo: photo_2, subject: runner)
end
end
end
和所有走向綠色。完善!
...不是那麼快。當我運行整個測試套件時,根據種子順序,我現在遇到了問題。
似乎class Print; end
行有時可能會覆蓋print.rb
的Print(它明顯從ActiveRecord繼承)的定義,因此會在套件中的各個點上失敗一堆測試。一個例子是:
NoMethodError:
undefined method 'reflect_on_association' for Print:Class
這使得一個不愉快的套件。
有關如何解決這個問題的任何建議。雖然這只是一個例子,但是服務直接引用模型的方法的次數很多,而且我已經採取了上述方法將它們剔除。有沒有更好的辦法?
打印類沒有加載,雖然。我明確地試圖避免包含print.rb,因爲它依賴於ActiveRecord,因此會使spec測試變得緩慢。 運行您的代碼將導致: 'NameError: 未初始化的常量Print' – idrysdale
是從您的代碼中調用的'reflect_on_association'方法嗎? –
不,它會在整個測試套件的其他地方打印,因爲它只是一個「ActiveRecord :: Reflection」方法 – idrysdale