[ruby] rspec에서 모듈 테스트

rspec에서 모듈 테스트에 대한 모범 사례는 무엇입니까? 몇 가지 모델에 포함되는 일부 모듈이 있으며 현재로서는 각 모델에 대해 중복 테스트가 있습니다 (차이가 거의 없음). 그것을 건조시키는 방법이 있습니까?



답변

rad way =>

let(:dummy_class) { Class.new { include ModuleToBeTested } }

또는 모듈을 사용하여 테스트 클래스를 확장 할 수 있습니다.

let(:dummy_class) { Class.new { extend ModuleToBeTested } }

‘let’을 사용하는 것은 before (: each)에서 더미 클래스를 정의하기 위해 인스턴스 변수를 사용하는 것보다 낫습니다.

RSpec let ()을 언제 사용합니까?


답변

마이크가 말한 것. 다음은 간단한 예입니다.

모듈 코드 …

module Say
  def hello
    "hello"
  end
end

사양 조각 …

class DummyClass
end

before(:each) do
  @dummy_class = DummyClass.new
  @dummy_class.extend(Say)
end

it "get hello string" do
  expect(@dummy_class.hello).to eq "hello"
end


답변

개별적으로 테스트하거나 클래스를 조롱하여 테스트 할 수있는 모듈의 경우 다음 라인을 따라 무언가를 좋아합니다.

기준 치수:

module MyModule
  def hallo
    "hallo"
  end
end

투기:

describe MyModule do
  include MyModule

  it { hallo.should == "hallo" }
end

중첩 된 예제 그룹을 가로채는 것은 잘못된 것처럼 보이지만 간결함을 좋아합니다. 이견있는 사람?


답변

rspec 홈페이지에서 더 나은 솔루션을 찾았습니다. 분명히 공유 예제 그룹을 지원합니다. 에서 https://www.relishapp.com/rspec/rspec-core/v/2-13/docs/example-groups/shared-examples !

공유 예제 그룹

공유 예제 그룹을 작성하고 해당 그룹을 다른 그룹에 포함시킬 수 있습니다.

크고 작은 제품의 모든 버전에 적용되는 동작이 있다고 가정하십시오.

먼저, “공유 된”행동을 제외하십시오 :

shared_examples_for "all editions" do
  it "should behave like all editions" do
  end
end

Large 및 Small 에디션의 동작을 정의해야하는 경우 it_should_behave_like () 메소드를 사용하여 공유 동작을 참조하십시오.

describe "SmallEdition" do
  it_should_behave_like "all editions"
  it "should also behave like a small edition" do
  end
end


답변

내 머리 위로 테스트 스크립트에 더미 클래스를 만들고 모듈을 포함시킬 수 있습니까? 그런 다음 더미 클래스가 예상 한대로 동작하는지 테스트하십시오.

편집 : 의견에서 지적했듯이 모듈이 혼합 된 클래스에 일부 동작이 나타날 것으로 예상되면 해당 동작의 인형을 구현하려고합니다. 모듈이 임무를 수행하기에 만족할만큼 충분합니다.

즉, 모듈이 호스트에서 많은 것을 기대할 때 (내가 “host”라고 말합니까?) 클래스에서 디자인에 대해 약간 긴장할 것입니다. 상속 트리에 새로운 기능을 제공하면 모듈이 가질 수있는 기대치를 최소화하려고 노력하고 있다고 생각합니다. 내 디자인이 불쾌한 융통성이없는 일부 영역을 개발하기 시작한다는 것이 나의 관심사입니다.


답변

받아 들인 대답은 내가 생각하는 정답이지만 rpsecs shared_examples_forit_behaves_like방법 을 사용하는 방법에 대한 예를 추가하고 싶었습니다 . 코드 스 니펫에서 몇 가지 트릭을 언급했지만 자세한 내용은이 relishapp-rspec-guide를 참조하십시오 .

이를 통해 모듈을 포함하는 모든 클래스에서 모듈을 테스트 할 수 있습니다. 따라서 실제로 응용 프로그램에서 사용하는 것을 테스트하고 있습니다.

예를 보자.

# Lets assume a Movable module
module Movable
  def self.movable_class?
    true
  end

  def has_feets?
    true
  end
end

# Include Movable into Person and Animal
class Person < ActiveRecord::Base
  include Movable
end

class Animal < ActiveRecord::Base
  include Movable
end

이제 우리 모듈을위한 스펙을 만들어 보자 : movable_spec.rb

shared_examples_for Movable do
  context 'with an instance' do
    before(:each) do
      # described_class points on the class, if you need an instance of it: 
      @obj = described_class.new

      # or you can use a parameter see below Animal test
      @obj = obj if obj.present?
    end

    it 'should have feets' do
      @obj.has_feets?.should be_true
    end
  end

  context 'class methods' do
    it 'should be a movable class' do
      described_class.movable_class?.should be_true
    end
  end
end

# Now list every model in your app to test them properly

describe Person do
  it_behaves_like Movable
end

describe Animal do
  it_behaves_like Movable do
    let(:obj) { Animal.new({ :name => 'capybara' }) }
  end
end


답변

이건 어떤가요:

describe MyModule do
  subject { Object.new.extend(MyModule) }
  it "does stuff" do
    expect(subject.does_stuff?).to be_true
  end
end