RSpec에서 "any_instance" "should_receive"를 여러 번 말하는 방법
여러 레코드가있는 여러 csv 파일을 데이터베이스로 가져 오는 가져 오기 컨트롤러가 레일에 있습니다. RSpec을 사용하여 레코드가 실제로 저장되었는지 RSpec에서 테스트하고 싶습니다.
<Model>.any_instance.should_receive(:save).at_least(:once)
그러나 다음과 같은 오류가 발생합니다.
The message 'save' was received by <model instance> but has already been received by <another model instance>
컨트롤러의 인위적인 예 :
rows = CSV.parse(uploaded_file.tempfile, col_sep: "|")
ActiveRecord::Base.transaction do
rows.each do |row|
mutation = Mutation.new
row.each_with_index do |value, index|
Mutation.send("#{attribute_order[index]}=", value)
end
mutation.save
end
RSpec을 사용하여이를 테스트 할 수 있습니까? 아니면 해결 방법이 있습니까?
이에 대한 새로운 구문이 있습니다.
expect_any_instance_of(Model).to receive(:save).at_least(:once)
다음은 : new 메서드를 재정의하지 않아도되는 더 나은 대답입니다.
save_count = 0
<Model>.any_instance.stub(:save) do |arg|
# The evaluation context is the rspec group instance,
# arg are the arguments to the function. I can't see a
# way to get the actual <Model> instance :(
save_count+=1
end
.... run the test here ...
save_count.should > 0
스텁 메서드는 제약 조건이없는 모든 인스턴스에 연결할 수 있으며 do 블록은 올바른 횟수로 호출되었는지 확인하기 위해 확인할 수있는 개수를 만들 수 있습니다.
업데이트-새 rspec 버전에는 다음 구문이 필요합니다.
save_count = 0
allow_any_instance_of(Model).to receive(:save) do |arg|
# The evaluation context is the rspec group instance,
# arg are the arguments to the function. I can't see a
# way to get the actual <Model> instance :(
save_count+=1
end
.... run the test here ...
save_count.should > 0
나는 마침내 나를 위해 작동하는 테스트를 만들었습니다.
mutation = FactoryGirl.build(:mutation)
Mutation.stub(:new).and_return(mutation)
mutation.should_receive(:save).at_least(:once)
stub 메서드는 save 메서드를 여러 번받는 단일 인스턴스를 반환합니다. 단일 인스턴스이기 때문에 any_instance
메서드를 삭제 하고 at_least
메서드를 정상적으로 사용할 수 있습니다 .
이런 스텁
User.stub(:save) # Could be any class method in any class
User.any_instance.stub(:save) { |*args| User.save(*args) }
그런 다음 다음과 같이 기대하십시오.
# User.any_instance.should_receive(:save).at_least(:once)
User.should_receive(:save).at_least(:once)
이것은 원래 방법으로 프록시 할 필요가 없기 때문에 를 사용하기 위해이 요점을 단순화 한 것입니다 any_instance
. 다른 용도에 대해서는 그 요점을 참조하십시오.
이것은 더 이상 지원하지 않는 RSpec 3.3을 사용하는 Rob의 예 Foo.any_instance
입니다. 루프에서 객체를 만들 때 유용하다는 것을 알았습니다.
# code (simplified version)
array_of_hashes.each { |hash| Model.new(hash).write! }
# spec
it "calls write! for each instance of Model" do
call_count = 0
allow_any_instance_of(Model).to receive(:write!) { call_count += 1 }
response.process # run the test
expect(call_count).to eq(2)
end
제 경우는 조금 달랐지만이 질문에 답을 여기에 떨어 뜨릴 생각이었습니다. 제 경우에는 주어진 클래스의 인스턴스를 스텁하고 싶었습니다. 을 사용할 때 동일한 오류가 발생했습니다 expect_any_instance_of(Model).to
. 으로 변경하면 allow_any_instance_of(Model).to
문제가 해결되었습니다.
Check out the documentation for some more background: https://github.com/rspec/rspec-mocks#settings-mocks-or-stubs-on-any-instance-of-a-class
You may try to count the number of new
on the class. That is not actually tests the number of save
s but may be enough
expect(Mutation).to receive(:new).at_least(:once)
If there is the only expectation of how many times it was saved. Then you probably want to use spy()
instead of fully functioning factory, as in Harm de Wit
own answer
allow(Mutation).to receive(:new).and_return(spy)
...
expect(Mutation.new).to have_received(:save).at_least(:once)
'Nice programing' 카테고리의 다른 글
이미지 주위에 텍스트를 배치하는 방법 (0) | 2020.11.18 |
---|---|
Reactive Framework, PLINQ, TPL 및 Parallel Extensions는 서로 어떤 관련이 있습니까? (0) | 2020.11.17 |
jsFiddle에서 GitHub 파일 참조 (0) | 2020.11.17 |
여러 연결에서 동시에 SQLite 데이터베이스를 읽고 쓸 수 있습니까? (0) | 2020.11.17 |
모든 하위 디렉토리에서 특정 파일 유형을 tar하는 방법은 무엇입니까? (0) | 2020.11.17 |