2012-05-11 2 views
3

다음 코드는 작동하지 않지만, 최고의 나는 또한 내가 주제로 를 초기화 내부 맥락에서 지역 변수를 사용하려고Rspec에서 주변 컨텍스트의 주제에 액세스 할 수 있습니까?

context "this context describes the class" do 

    subject do 
    # described class is actually a module here 
    c = Class.new.extend(described_class) 
    c.some_method_that_has_been_added_through_extension 
    c 
    end 

    # ... testing the class itself here ... 

    context "instances of this class" do 

    subject do 
     # this doesn't work because it introduces a endless recursion bug 
     # which makes perfectly sense 
     subject.new 
    end 

    end 

end 

달성하기 위해 노력하고있어 보여,하지만 운. 내부 범위의 내 주제 정의 내에서 외부 범위의 주제에 액세스 할 수있는 방법이 있습니까? 분명히 내부 상황인스턴스 변수를 사용하는 대신 subject하지만 subject.call하지를 초기화 작동

답변

0

뭔가. 과목은 Procs입니다. 따라서 첫 번째 접근 방식은 효과가 없었습니다.

context "instances of this class" do 

    klass = subject.call 
    subject { klass.new } 

end 
3

# 주체를 사용하면 문제가 발생할 수 있습니다. #its와 같은 짧은 수표와 함께 사용하는 것은 "주로"의도 된 것입니다.

또한 테스트하는 이름/의도를 가릴 수 있으므로 읽기가 더 어려워 질 수 있습니다. 내가 가장 가능성이 그것을 쓰기 얼마나 대신 http://blog.davidchelimsky.net/blog/2012/05/13/spec-smell-explicit-use-of-subject/

이하자를 사용해보십시오, 여기에 https://www.relishapp.com/rspec/rspec-core/v/2-10/docs/helper-methods/let-and-let

됩니다 : 여기에 데이비드 Chelimsky가 #subject 및 #let의 주제와 의도를 드러내는에서 자신의 역할에 쓴 블로그 게시물입니다.

context "this context describes the class" do 
    let(:name_of_the_module) { Class.new.extend(described_class) } 
    before do 
    c.some_method_that_has_been_added_through_extension 
    end 

    # ... testing the class itself here ... 

    context "instances of this class" do 

    let(:better_name_that_describes_the_instance) { klass.new } 

    # ... test the instance 
    end 

end 

당신이 모든 주제를 사용할지 여부를 다시 방문 할 수 있습니다 (!) 참고. 나는 거의 모든 경우에 #let을 선호한다. YMMV

0

나는 여러 가지 이유로이 문제에 대한 해결책을 찾고있었습니다. 값을 반환하거나 오류를 발생시킬 수있는 메서드를 테스트 할 때 종종 두 개의 컨텍스트, 즉 raise_error의 proc로 한 번 정상적으로 한 번 반복해야합니다.

lets과 같이 subjects 개의 이름을 지정할 수 있다는 것을 발견했습니다. 이제 새 subject 내의 바깥 쪽 범위에서 subject이라는 이름을 참조하겠습니다. 예를 들면 다음과 같습니다.

describe 'do_some_math' do 
    let!(:calculator) { create(:calculator) } 

    # proc to be used with raise_error 
    subject(:do_some_math) { 
    -> { calculator.do_some_math(with, complicated, args) } 
    } 

    context 'when something breaks' do 
    it { is_expected.to raise_error } # ok 
    end 

    context 'when everything works' do 

    # here we call the named subject from the outer scope: 
    subject { do_some_math.call } # nice and DRY 

    it { is_expected.to be_a(Numeric) } # also ok! 
    end 
end 
관련 문제