RSpec stubbed 메서드가 순서대로 다른 값을 반환 할 수 있습니까?
다른 개체 인 Members location의 location출력 을 병합 하는 메서드가있는 모델 Family가 있습니다. (구성원은 가족과 연결되어 있지만 여기서는 중요하지 않습니다.)
예를 들어, 주어진
- member_1 has
location== 'San Diego (여행 중, 5 월 15 일 반환)' - member_2에는
location== 'San Diego'가 있습니다.
Family.location이 'San Diego (member_1 여행 중, 5 월 15 일 반환)'를 반환 할 수 있습니다. 세부 사항은 중요하지 않습니다.
Family.location의 테스트를 단순화하기 위해 Member.location을 스텁하고 싶습니다. 그러나 위의 예에서와 같이 두 개의 다른 (지정된) 값을 반환해야합니다. 이상적으로는의 속성을 기반으로 member하지만 단순히 시퀀스에서 다른 값을 반환하는 것은 괜찮습니다. RSpec에서이 작업을 수행하는 방법이 있습니까?
다음과 같이 각 테스트 예제 내에서 Member.location 메서드를 재정의 할 수 있습니다.
it "when residence is the same" do
class Member
def location
return {:residence=>'Home', :work=>'his_work'} if self.male?
return {:residence=>'Home', :work=>'her_work'}
end
end
@family.location[:residence].should == 'Home'
end
하지만 이것이 좋은 습관이라고 생각하지 않습니다. 어쨌든 RSpec이 일련의 예제를 실행할 때 원래 클래스를 복원하지 않으므로 이러한 종류는 후속 예제를 "독"으로 덮어 씁니다.
그렇다면 스텁 메서드가 각 호출에서 다른 지정된 값을 반환하도록하는 방법이 있습니까?
호출 될 때마다 다른 값을 반환하도록 메서드를 스텁 할 수 있습니다.
allow(@family).to receive(:location).and_return('first', 'second', 'other')
따라서 처음 호출 @family.location할 때 'first'를 반환하고 두 번째로 'second'를 반환하고 이후에 호출 할 때마다 'other'를 반환합니다.
RSpec 3 구문 :
allow(@family).to receive(:location).and_return("abcdefg", "bcdefgh")
어떤 이유로 이전 구문을 사용하려는 경우에도 다음을 수행 할 수 있습니다.
@family.stub(:location).and_return('foo', 'bar')
허용 된 솔루션은 특정 수의 호출이 있고 특정 데이터 시퀀스가 필요한 경우에만 사용해야합니다. 하지만 호출 할 호출 수를 모르거나 매번 다른 데이터의 순서 만 신경 쓰지 않는다면 어떨까요? OP가 말했듯이 :
시퀀스에서 다른 값을 반환하는 것만으로도 괜찮습니다.
문제 and_return는 반환 값이 메모된다는 것입니다. 동적으로 반환하더라도 항상 동일한 결과를 얻을 수 있다는 의미입니다.
예
allow(mock).to receive(:method).and_return(SecureRandom.hex)
mock.method # => 7c01419e102238c6c1bd6cc5a1e25e1b
mock.method # => 7c01419e102238c6c1bd6cc5a1e25e1b
또는 실제 예는 공장을 사용하고 동일한 ID를 얻는 것입니다.
allow(Person).to receive(:create).and_return(build_stubbed(:person))
Person.create # => Person(id: 1)
Person.create # => Person(id: 1)
이러한 경우 매번 코드가 실행되도록 메서드 본문을 스텁 할 수 있습니다.
allow(Member).to receive(:location) do
{ residence: Faker::Address.city }
end
Member.location # => { residence: 'New York' }
Member.location # => { residence: 'Budapest' }
self이 컨텍스트 를 통해 Member 개체에 액세스 할 수 없지만 테스트 컨텍스트의 변수를 사용할 수 있습니다.
예
member = build(:member)
allow(member).to receive(:location) do
{ residence: Faker::Address.city, work: member.male? 'his_work' : 'her_work' }
end
위의 솔루션 개요를 시도했지만 내 기능이 작동하지 않습니다. 대체 구현으로 스터 빙하여 문제를 해결했습니다.
다음과 같은 것 :
@family.stub(:location) { rand.to_s }
'Nice programing' 카테고리의 다른 글
| iPhone의 StatusBar에보기 추가 (0) | 2020.11.26 |
|---|---|
| Linux에서 홈 디렉토리 가져 오기 (0) | 2020.11.26 |
| 웹 애플리케이션에서 Log4Net 구성 (0) | 2020.11.26 |
| 키 / 값 쌍을 얻기 위해 Javascript에서 JSON 응답 구문 분석 (0) | 2020.11.26 |
| '잘못된 업데이트 : 섹션 0의 잘못된 행 수 (0) | 2020.11.26 |