여러 모델에 접촉하는 서비스 개체에 대한 Rspec 테스트를 작성하고 있지만 테스트가 메서드의 내부에 너무 의존적이어서 매우 중요하지 않습니다. 실제로 (성능) 시험 데이터베이스에 아무것도 저장하지 않고 동작을 모의/스텁 복식을 사용하고 싶습니다서비스 개체 테스트를위한 Rspec advice
class MealServicer
def self.serve_meal(meal, customer)
meal.update_attributes(status: "served", customer_id: customer.id)
order = customer.order
OrderServicer.add_meal_to_order(meal, order)
CRM.update_customer_record(customer) // external API call
end
end
예를 들면 다음과 같습니다이다. 그러나 메시지에 응답하는 double을 만들면 serve_meal() 메서드의 특정 구현을 테스트하는 것처럼 느껴지며이 테스트는 특정 구현과 너무 얽혀 있습니다. 예를 들어, 내 customer
이 order
에 이중 응답하고 order
스텁을 반환하는지 확인해야합니다. 본질적으로, 모든 것이 단지 두 배일 때, 복소가 다른 두 배의 값을 반환 하는지를 명시하여 모든 의존성을 명시해야 할 때, 테스트가 꽤 의미가없는 것처럼 느껴집니다.
it "has a working serve_meal method" do
meal = double(:meal)
customer = double(:customer)
order = double(:order)
allow(customer).to_receive(:order).and_return(order)
allow(OrderServicer).to_receive(:add_meal_to_order).and_return(true)
allow(CRM).to_receive(:update_customer_record).and_return(true)
expect(meal).to receive(:update_attributes).once
expect(OrderServicer).to receive(:add_meal_to_order).once
expect(CRM).to receive(:update_customer_record).once
end
합니다 (DATBASE에 아마도 저장) 적절하게 연결되어 실제 식사, 고객 및 주문 개체의 인스턴스를보다 철저하고 의미있게 다른이를 테스트하는 또 다른 방법이 있나요, 그리고 그 MealServicer.serve_meal을 확인하십시오 여기를 참조하십시오 (...) 예상대로 개체 속성을 업데이트합니까? update_attributes는 저장 호출을 수행하고 Service 객체 메소드에 포함 할 메소드 중 몇 가지를 수행하기 때문에 결국 데이터베이스에 저장이 끝납니다.
마지막으로 테스트가 구현에 의존하기 때문에 TDD 옹호자가 권장하는 방법보다 먼저 테스트를 작성할 수 없습니다. 이것은 거꾸로 느낀다. Performant하지만 유용한 테스트 작성에 대한 조언은 무엇입니까?
그래, 당신은 기본적으로 실제 코드의 대부분을 스텁하고, 그래서 정말 당신이 실제로에서 줄을 삭제하지 않는 한 방법이 실패 할 경우가되지 않습니다 . 객체의 본질을 감안할 때, 이런 종류의 비즈니스 로직은 단위 테스트 대신 통합 레벨에서 더 많은 테스트를 수행 할 것입니다. 당신은 다른 일을하는 여러 객체를 다루고 있습니다. 그리고 실제로 당신의 방법을 읽으면, 그것은 특집 사양처럼 들립니다. 앱에서 MealServicer를 어떻게 활용하고 있는지 궁금 할 것입니다. 그러나 실제 객체 사용에 대해서는 걱정하지 마십시오.해당 메소드가 호출 될 때 발생할 것으로 예상되는 것에 대한 테스트를 작성하십시오. – agmcleod