ruby on rails 4 - Use rspec to test class methods are calling scopes -


i have created rspec tests scopes (scope1, scope2 , scope3) , pass expected add tests class method have called controller (the controller calls scopes indirectly via class method):

def self.my_class_method(arg1, arg2)   scoped = self.all    if arg1.present?     scoped = scoped.scope1(arg1)   end    if arg2.present?     scoped = scoped.scope2(arg2)   elsif arg1.present?     scoped = scoped.scope3(arg1)   end    scoped end 

it seems bit redundant run same scope tests each scenario in class method when know pass assume need ensure different scopes called/applied dependant on args being passed class method.

can advise on rspec test like.

i thought might along lines of

expect_any_instance_of(mymodel.my_class_method(arg1, nil)).to receive(:scope1).with(arg1, nil) 

but doesn't work.

i appreciate confirmation that's necessary test in situation when i've tested scopes anyway reassurring.

the rspec code wrote testing internal implementation of method. should test method returns want return given arguments, not in way. way, tests less brittle. example if change scope1 called, won't have rewrite my_class_method tests.

i creating number of instances of class , call method various arguments , check results expect.

i don't know scope1 , scope2 do, made example arguments name attribute model , scope methods retrieve models except name. obviously, whatever real arguments , scope methods should put in tests, , should modify expected results accordingly.

i used to_ary method expected results since self.all call returns activerecord association , therefore wouldn't otherwise match expected array. use includes , does_not_includes instead of eq, perhaps care order or something.

describe mymodel   describe ".my_class_method"     # helpful use factorygirl here     # note bang (!) version of let     let!(:my_model_1) { mymodel.create(name: "alex") }     let!(:my_model_2) { mymodel.create(name: "bob") }     let!(:my_model_3) { mymodel.create(name: "chris") }      context "with nil arguments"       let(:arg1) { nil }       let(:arg2) { nil }       "returns all"         expected = [my_model_1, my_model_2, my_model_3]         expect_my_class_method_to_return expected       end     end      context "with first argument equal model's name"       let(:arg1) { my_model_1.name }       let(:arg2) { nil }       "returns except models name matching argument"         expected = [my_model_2, my_model_3]         expect_my_class_method_to_return expected       end        context "with second argument equal model's name"         let(:arg1) { my_model_1.name }         let(:arg2) { my_model_2.name }         "returns except models name matching either argument"           expected = [my_model_3]           expect_my_class_method_to_return expected         end       end     end   end    private     def expect_my_class_method_to_return(expected)     actual = described_class.my_class_method(arg1, arg2).to_ary     expect(actual).to eq expected   end end 

Comments

Popular posts from this blog

python - TypeError: start must be a integer -

c# - DevExpress RepositoryItemComboBox BackColor property ignored -

django - Creating multiple model instances in DRF3 -