2016-07-27 4 views
1

질문을 잘못 말하면 정확한 내용을 입력하십시오.rspec 단위 테스트에서 기대와 함께 조롱을 선택하십시오.

class Filters 
    def self.good ducks 
    ducks.select(&:good?) 
    end 
end 

이 같은 방법을 테스트 할 물론 가능하다 :

다음 코드 가정

describe Filters, '#good' do 
    let(:good) { double(:good, good?: true) } 
    let(:bad) { double(:bad, good?: false) } 

    subject { Filters.good(ducks) } 

    context 'none' do 
    let(:ducks) { [] } 
    it { is_expected.to eq [] } 
    end 

    context 'one good' do 
    let(:ducks) { [good] } 
    it { is_expected.to eq [good] } 
    end 

    context 'one bad' do 
    let(:ducks) { [bad] } 
    it { is_expected.to eq [] } 
    end 

    context 'one good and one bad' do 
    let(:ducks) { [good, bad] } 
    it { is_expected.to eq [good] } 
    end 

    context 'some good and some bad' do 
    let(:ducks) { [good, bad, bad, good, bad, good] } 
    it { is_expected.to eq [good, good, good] } 
    end 
end 

을하지만 모든 없음 그러나 물론 실제로 사건 (모든 열거/하나/일부/많은 조합에 대한 진실/거짓 good 상태) 나는 실제로 내가 단위 방법을 테스트하고 있지만 통합 이후로 그것을 테스트하자 ""에 select "leak"의 동작에 대한 지식이 있으면 테스트 사례 수가 늘어납니다. 어떤 의미에서는 내 테스트 케이스가 select 메소드의 동작을 테스트하고 있습니다.

내게는 mocking을 사용하고 테스트보다는 검사에서와 같이 메서드가 올바르게 위임하는 것이 더 적합합니다. 하나가 스스로 작성한 기능과 통합했다면 할 수있는 것처럼. 예를 들어 우리와 비슷한 것. expect(obj).to receive(:foo).with(:bar)라고 할 수 있습니다.

아래의 예는 작동하지 않지만 모든 사례를 나열하는 대신 내가하고 싶은 생각을 전달한다고 생각합니다.

describe Filters, '#good' do 
    it 'returns only good ones' do 
    ducks = double(:ducks) 
    expect(ducks).to receive(:filter).with(:good?).and_return(:filtered) 
    expect(Filters.good(ducks).to eq) 
    end 
end 

예는 인수가 쓸모없는 방법이라고 말하고 Filter.good의 사용자가 단순히 직접적으로 select -statement를 이동하는 경우에만 필요가 이동한다는 사실을 고려하시기 바랍니다 select를 사용하는 것을 방지하기 위해 너무 사소한 것처럼 보일 수 있습니다 다른 위치로 테스트.

내가 여기에 근본적인 것을 오해하고 있거나 간과하고 있습니까?

Ps 1. 간략하게 몇 가지 테스트 케이스를 무시합니다.

시 2. 내가 단위하지 통합의 필요성을 강조하고있어 이유의 짧은 버전이 시험이 비디오입니다 : https://www.youtube.com/watch?v=VDfX44fZoMc

편집 : 이 질문 문구에 더 좋은 방법은 아마도 것 : 첫 번째 테스트는 클래식리스트Filters.good을 테스트하는 방법의 요지의 예입니다. 그러나 모의 객체은 어떻게 테스트합니까?

+0

해결책을 찾았습니까? –

+0

@PaulFioravanti 제공하신 답변에 감사드립니다. 그러나 아직 해결책이 없다고 생각됩니다. 질문에 대한 설명을 추가하고 있습니다. – chris

답변

0

100 % 확신 할 수는 없지만 공장 소녀와 특히 공장 소녀 create_list를 살펴 보겠습니다. 하나를 나쁜 것으로 수정. https://github.com/thoughtbot/factory_girl/blob/master/GETTING_STARTED.md 그리고 정말로 원한다면 각자에게 다음을 기대할 수 있습니다. 그것을 요구했다. 끝에있는 목록이 올바른 목록에 있는지 확인하는 것이 좋을 수도 있습니다. 당신의 행동이 도움이 될 수있는 실제 사례를 제시하지만, 공장 소녀 목록을 만드는 것이 최소한 하나의 문제를 해결할 것이라고 생각합니다.

수정 :

let(:duck){double :duck} 
describe Filters, '#good' do 
    it 'returns only good ones' do 
    ducks = [duck, duck, duck] 
    expect(ducks).to receive(:good).exactly(3).times 
    Filters.good(ducks) 
    end 
end 
+0

답변 해 주셔서 감사합니다. 나는이 질문을 다시 말하고 예제를 추가했다. – chris

+0

자, 답을 수정하겠습니다 : P – stephenlloyd

0

시험 방법은 필터링을 수행하기 때문에, 나는 당신이 good?의 반응에 의해 제외하고 (방법에서 코드를 스텁에 대한 필요없이 작성된 간결 하나의 단위 테스트를 얻을 수 있다고 생각 좋은 또는 나쁜 오리가에 얼마나 많은 사양은 상관하지 않는다

class Filters 
    def self.good(ducks) 
    ducks.select(&:good?) 
    end 
end 

RSpec.describe Filters do 
    describe '.good' do 
    let(:good_duck) { double(:good, good?: true) } 
    let(:bad_duck) { double(:bad, good?: false) } 
    let(:ducks) { [good_duck, bad_duck] } 
    let(:good) { described_class.good(ducks) } 

    it 'returns only good ducks' do 
     expect(good).to include(good_duck) 
     expect(good).not_to include(bad_duck) 
    end 
    end 
end 

: 당신의 결과 세트에서 객체의) 포함에 대한 테스트를 통해) 전달 (또는 그 부족됩니다 컬렉션의 모든 요소 th로 전달되는 컬렉션 e Filters.good 메서드는 good?true으로 응답하는 모든 개체가 결과 집합에 포함되며 false으로 응답하는 개체가 없으므로 context을 제외하고 해당 질문에 설명 된 context 블록이 필요하지 않습니다. 빈 배열을 테스트합니다.

+0

그러나 이것은 구현에 대해 잘못된 긍정을 줄 것입니다 :'[ducks.first]'는 여러 경우를 테스트 할 필요성을 다시 한번 시사합니다. – chris

+0

@chris 죄송합니다. "구현에 대한 거짓 긍정 :'[ducks.first]'"가 무슨 뜻인지 이해할 수 없습니다. 콜렉션의 첫 번째 요소가있는 배열은 어디에서 재생됩니까? –

+0

'Filters.good (ducks)'의 구현이'[ducks.first]'인 경우 테스트가 (잘못) 통과합니다. – chris

관련 문제