Динамические спецификации в Rspec
Иногда бывают моменты, когда Вам может быть нужно создать набор спецификаций для rspec, отличающихся одним-двумя вызовами или параметрами. У меня в проекте сложилась такая ситуация, и я решил попробовать использовать возможности Ruby для динамической генерации кода чтобы, сделать spec-файлы короче и избежать дублирования.
У меня есть хелпер, который используется в нескольких универсальных темплейтах для генерации похожих страниц. Этот хелпер возвращвет URL по набору параметров и типу ссылки. Он может принимать 5 различных типов ссылок и выбрасывает исключение с случаях, когда тип ссылки не поддерживается. Без использования динамической генерации кода мне пришлось бы создать 5 различных спецификаций (по одной для каждого типа ссылок) для того, чтобы иметь возможность видеть каждый тип ссылок отдельной строкой в результатах теста. С использованием же динамической генерации код выглядит примерно так:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | describe VideoHelper, 'when profile_video_url method called' do before do @user = mock('user') end url_types = { 'personal_feed' => 'personal_feed', 'favorites' => 'favorites', 'voted' => 'voted_videos', 'posted' => 'posted_videos', 'commented' => 'commented_videos' } url_types.each do |url_type, route| it "should return #{route}_url for #{url_type} type urls" do @user.should_receive(:login).at_least(1).times.and_return('login') profile_video_url(url_type, @user, 2, 'expert').should == send("#{route}_url", @user, 2, 'expert') end end it 'should raise ArgumentError("Invalid feed type") on invalid url_types' do lambda { profile_video_url('crap', @user, 2, 'expert') }.should raise_error(ArgumentError, 'Invalid feed type') end end |
Эта техника может быть использована даже для целых describe-секций, но я не буду приводить здесь гору кода, который получился у меня. Так или иначе, идея предельно проста: вы можете использовать любые циклы с секцией describe внутри и вызовами метода send() для динамического конструирования Вашего кода.
Related posts:
