programing

RSpeclet()을 사용해야 하는 경우

closeapi 2023. 5. 31. 15:56
반응형

RSpeclet()을 사용해야 하는 경우

인스턴스(instance) 변수를 설정할 때 블럭 앞에 사용하는 경향이 있습니다.그런 다음 이러한 변수를 사용하여 예를 들어 보겠습니다.나는 최근에 우연히let()RSpec 문서에 따르면, 그것은 다음과 같이 사용됩니다.

메모화된 도우미 메서드를 정의합니다.이 값은 동일한 예에서 여러 호출에 걸쳐 캐시되지만 예제에서는 캐시되지 않습니다.

블록 앞에 인스턴스 변수를 사용하는 것과 어떻게 다릅니까?또한 언제 사용해야 합니까?let()before()?

나는 항상 선호합니다.let다음과 같은 이유로 인스턴스 변수에 추가됩니다.

  • 인스턴스 변수는 참조될 때 존재합니다., 변수의 됩니다.nil이는 미묘한 버그와 잘못된 긍정으로 이어질 수 있습니다. 때부터let메소드를 만들면 다음과 같은 효과를 얻을 수 있습니다.NameError철자를 틀렸을 때, 제가 선호하는 것입니다.또한 사양을 리팩터링하기도 더 쉽습니다.
  • A before(:each)예제가 후크에 정의된 인스턴스 변수를 사용하지 않더라도 각 예제 앞에서 후크가 실행됩니다.일반적으로 이것은 큰 문제가 아니지만, 인스턴스 변수를 설정하는 데 시간이 오래 걸리면 사이클이 낭비됩니다. 경의우로 정의된 let초기화 코드는 예제에서 호출한 경우에만 실행됩니다.
  • 예제의 참조 구문을 변경하지 않고 예제의 로컬 변수에서 직접 렛으로 리팩터링할 수 있습니다.변수에 할 경우 ).@).
  • 이것은 약간 주관적이지만, Mike Lewis가 지적했듯이, 저는 이것이 스펙을 읽기 쉽게 만든다고 생각합니다.나는 나의 인 대상을 종개정구좋다습으로 .let그리고 나의 것을 유지합니다.it단타를 막다

관련 링크는 여기에서 찾을 수 있습니다: http://www.betterspecs.org/ #let

변수 (instance) 사용의 차이let()은 것은입니다.let()게으르게 행동합니다.즉,let()정의된 메서드를 처음 실행할 때까지 평가되지 않습니다.

before그리고.let은 것은입니다.let()변수 그룹을 '슬래딩' 스타일로 정의하는 데 유용한 방법을 참조하십시오.이렇게 하면 코드를 단순화하여 스펙이 조금 더 좋아 보입니다.

rspec 테스트에서 인스턴스 변수의 모든 사용을 let()으로 완전히 대체했습니다.작은 Rspec 클래스를 가르치는 데 사용한 친구를 위해 간단한 예제를 작성했습니다. http://ruby-lambda.blogspot.com/2011/02/agile-rspec-with-let.html

여기에 있는 다른 답변 중 일부에서 알 수 있듯이, let()는 게으르게 평가되므로 로드가 필요한 항목만 로드됩니다.이것은 사양을 건조시켜 더 읽기 쉽게 만듭니다.사실 저는 컨트롤러에서 사용할 Rspeclet() 코드를 inherited_resource gem 스타일로 이식했습니다.http://ruby-lambda.blogspot.com/2010/06/stealing-let-from-rspec.html

느린 평가와 더불어 ActiveSupport와 결합된 또 다른 이점은 다음과 같습니다.모든 것을 로드할 수 있는 사양/지원/동작에 대한 우려가 있으므로 애플리케이션에 적합한 자체 사양 미니 DSL을 생성할 수 있습니다.Rack 및 RESTful 리소스에 대한 테스트를 위해 작성했습니다.

제가 사용하는 전략은 공장-모든 것(기계사+위조/페이커를 통해)입니다.그러나 이전(: 각) 블록과 함께 사용하여 전체 예제 그룹에 대한 공장 사전 로드를 수행할 수 있으므로 사양이 더 빨리 실행될 수 있습니다. http://makandra.com/notes/770-taking-advantage-of-rspec-s-let-in-before-blocks

게으르게 평가하고 부작용 방법을 넣지 않는 이 중요합니다. 그렇지 않으면 각 방법을 쉽게 이전(:각)으로 변경할 수 없습니다.각 시나리오 전에 평가되도록 let 대신 let!을 사용할 수 있습니다.

: 여기반년대소리 5목후나않습다니지좋아하는서▁r▁▁like않▁heret습▁years니:spec여▁5'▁after▁donspec▁voice기지ing▁i▁of▁r하좋▁5.let아주 많이.

느린 평가는 종종 테스트 설정을 혼란스럽게 만듭니다.

설정에서 선언된 일부 항목이 실제로 상태에 영향을 미치지 않는 반면 다른 항목은 상태에 영향을 미치지 않는 경우 설정에 대해 추론하기가 어려워집니다.

결국, 좌절감 때문에 누군가는 그냥 변합니다.letlet!(나태한 평가 없이 동일한 것) 그들의 스펙을 작동시키기 위해.만약 이것이 그들에게 효과가 있다면, 새로운 습관이 생겨납니다: 새로운 사양이 오래된 스위트에 추가되었지만 그것이 작동하지 않을 때, 작가가 가장 먼저 시도하는 것은 무작위에 앞머리를 추가하는 것입니다.let전화가 걸려오는 전화.

곧 모든 성능 혜택이 사라집니다.

특수 구문이 rspec이 아닌 사용자에게는 일반적이지 않습니다.

나는 rspec의 트릭보다 루비를 우리 팀에게 가르치고 싶습니다.은 이 에서 유용합니다.let구문은 rspec에서만 유용합니다.

"장점"을 통해 우수한 설계 변경 사항을 쉽게 무시할 수 있습니다.

let()반복해서 만들고 싶지 않은 값비싼 의존성에 좋습니다.그것은 또한 그것과 잘 어울립니다.subject 통화 방식에 대한 것은 당신이 multi-discovery 에 대해 사용하는 것입니다.

값비싼 의존성과 큰 서명이 있는 메소드는 모두 코드를 더 잘 만들 수 있는 포인트입니다.

  • 코드의 나머지 부분에서 종속성을 분리하는 새로운 추상화를 도입할 수 있습니다(즉, 필요한 테스트가 더 적음).
  • 테스트 중인 코드가 너무 많이 수행되고 있을 수 있습니다.
  • 아마도 나는 원시적인 것들의 긴 목록 대신 더 똑똑한 것들을 주입해야 할 수 있습니다.
  • 어쩌면 제가 묻지마 범죄를 저질렀는지도 모릅니다.
  • 아마도 값비싼 코드가 더 빨리 만들어질 수 있을 것입니다(여기서는 너무 이른 최적화에 주의하십시오).

이 모든 경우에, 저는 rspec 마법의 진정제를 사용하여 어려운 테스트의 증상을 해결하거나 원인을 해결할 수 있습니다.지난 몇 년간 전자에 너무 많은 시간을 투자한 것 같고 이제는 더 나은 코드를 원합니다.

원래 질문에 답하기그러고 싶지는 않지만 여전히 사용하고 있습니다.let저는 대부분 팀의 나머지 스타일에 맞추기 위해 그것을 사용합니다. (세계 대부분의 Rails 프로그래머들은 이제 그들의 rspec 마법에 깊이 빠져있는 것 같습니다. 그래서 그것은 매우 자주 있습니다.)때때로 저는 제가 통제할 수 없는 코드에 테스트를 추가하거나 더 나은 추상화를 위해 재팩터링할 시간이 없을 때 사용합니다. 즉, 유일한 옵션이 진통제일 때입니다.

일적으로반,let()더 좋은 구문이고 타이핑하는 것을 절약합니다.@name곳곳에 있는 기호들하지만, 조심해, 공허!찾았습니다let()또한 변수는 사용하기 전까지는 실제로 존재하지 않기 때문에 미묘한 버그(또는 적어도 머리 긁힘)가 발생합니다. 기호: 기호를 : 추하는경우가경putslet()하려면 스펙을할 수 , 가 없으면 스펙을 통과할 수 .puts사양이 실패합니다. 이 미묘함을 발견했습니다.

나는 또한 그것을 발견했습니다.let()모든 상황에서 캐시하지 않는 것 같습니다!저는 그것을 제 블로그에 썼습니다: http://technicaldebt.com/ ?p=1242

저만 그런가요?

기본적으로 Proc로서 기능합니다.캐시도 있습니다.

한 명은 바로 발견한 차를 가지고 있습니다.변경 사항을 평가하는 규격 블록입니다.

let(:object) {FactoryGirl.create :object}

expect {
  post :destroy, id: review.id
}.to change(Object, :count).by(-1)

당신은 반드시 전화해야 할 것입니다.let예상 범위를 벗어났습니다. 즉, 당신이 전화하는 것입니다.FactoryGirl.create당신의 임대 구역에서.저는 보통 객체가 지속되는지 확인함으로써 이 작업을 수행합니다.

object.persisted?.should eq true

그렇지 않으면 다음과 같습니다.let블록은 게으른 인스턴스화로 인해 데이터베이스에서 실제로 변경이 발생하는 첫 번째 시간이라고 합니다.

갱신하다

메모를 추가하는 중입니다.코드 골프를 치거나 이 경우에는 이 답을 사용하여 rspec 골프를 치도록 주의하십시오.

이 경우에는 객체가 응답하는 어떤 방법을 호출하면 됩니다.그래서 나는 그것을 호출합니다._.persisted?개체에 대한 메서드를 진실로 지정합니다.제가 하려는 것은 객체를 인스턴스화하는 것입니다.빈칸이라고 부를 수 있습니까?아니면 0? 역시.요점은 테스트가 아니라 객체를 생명이라고 부르는 것입니다.

그래서 리팩터를 할 수 없습니다.

object.persisted?.should eq true

되려고

object.should be_persisted 

개체가 인스턴스화되지 않았기 때문에...게으릅니다.:)

업데이트 2

문제를 방지하기 위해 즉각적인 개체 생성을 위해 let! 구문을 활용합니다.비록 그것이 뱅글뱅글 하지 않는 렛의 게으름의 목적을 많이 꺾을 것에 주목하세요.

또한 경우에 따라 추가 옵션을 제공할 수 있으므로 제목 구문을 사용하는 대신 실제로 활용할 수도 있습니다.

subject(:object) {FactoryGirl.create :object}

before으로 기적으 "전은이 "합니본 "다의미 "로전 "를 의미합니다.before(:each)Rspec Book, copyright 2010, 228권.

before(scope = :each, options={}, &block)

사용합니다before(:each) 일부 수 있습니다.let데이터를 "it" 블록에 생성하는 방법입니다.이 경우 "it" 블록의 코드 수가 줄어듭니다.

사용합니다let어떤 예에서는 데이터가 필요하지만 다른 예에서는 필요하지 않습니다.

앞과 뒤 모두 "잇" 블록을 건조하는 데 좋습니다.

혼동을은 "let"과 .before(:all)"let"은 각 예제("it")에 대해 메서드와 값을 재평가하지만 동일한 예제에서 여러 호출에 걸쳐 값을 캐시합니다.자세한 내용은 여기에서 확인할 수 있습니다. https://www.relishapp.com/rspec/rspec-core/v/2-6/docs/helper-methods/let-and-let

Joseph 참고 - 데이터베이스 오브젝트를 작성하는 경우before(:all)트랜잭션에서 캡처되지 않으므로 테스트 데이터베이스에 손상된 부분을 남길 가능성이 훨씬 높습니다.사용하다before(:each)대신.

let와 그 게으른 평가를 사용하는 또 다른 이유는 다음과 같이 복잡한 객체를 선택하고 컨텍스트에서 let를 재정의하여 개별 조각을 테스트할 수 있기 때문입니다.

context "foo" do
  let(:params) do
     { :foo => foo,  :bar => "bar" }
  end
  let(:foo) { "foo" }
  it "is set to foo" do
    params[:foo].should eq("foo")
  end
  context "when foo is bar" do
    let(:foo) { "bar" }
    # NOTE we didn't have to redefine params entirely!
    it "is set to bar" do
      params[:foo].should eq("bar")
    end
  end
end

사용합니다let컨텍스트를 사용하여 API 사양에서 HTTP 404 응답을 테스트합니다.

리스를생기위사다니용합해성하소▁▁i▁use 사용합니다.let!는 하지만자식저를위장해기하나, 는원별을 합니다.let다음과 같이 표시됩니다.

let!(:country)   { create(:country) }
let(:country_id) { country.id }
before           { get "api/countries/#{country_id}" }

it 'responds with HTTP 200' { should respond_with(200) }

context 'when the country does not exist' do
  let(:country_id) { -1 }
  it 'responds with HTTP 404' { should respond_with(404) }
end

그것은 사양을 깨끗하고 읽기 쉽게 유지합니다.

언급URL : https://stackoverflow.com/questions/5359558/when-to-use-rspec-let

반응형