본문 바로가기

소프트웨어-이야기/테스트-자동화

[pytest] 함수의 매개변수로 기대한 값이 전달되었는지 확인하는 테스트코드 작성하기

pytest에서 테스트 코드를 작성할 때, 특정 함수의 매개변수로 기대한 값이 잘 넘어갔는지 확인하고 싶을 때가 있습니다. 


예를 들면, 외부 API와 연동하는 함수를 테스트해보고 싶을 때, 이 함수에 특정 값이 매개변수로 잘 전달되었는지 확인하고 싶어지죠. 

이럴 때는 mocker 클래스와 assert_called_with 함수를 사용하면 됩니다. 


예시

아래의 예시는 viewset에서 내부 함수를 호출했을 때, 기대한 매개변수를 잘 전달했는지 확인하는 테스트코드입니다.

class TestCommerceViewSet:
def test_purchase_구매_이벤트가_로그에_남는다(self, rf, mocker):

purchase_event = {'product_id': 1, 'created_time': datetime.now()}
logging_mocker = mocker.patch.object(
CommerceViewSet,
'_write_logging')
request = rf.post(
'/purchase', data={})
CommerceViewSet.as_view({'post': 'purchase'})(request)
logging_mocker.assert_called_with(purchase_event
)


* 테스트하고 싶은 함수를 mocker.patch.object으로 mocking 처리를 하면 되구요! 

* 그 다음에 테스트할 함수를 호출하구요!

* 그 다음에 mocking 처리를 했던 mocker 객체에서 기대한 매개변수가 전달되었는지, assert_called_with 함수로 테스트를 하면 됩니다 :) 


잡담

ruby on rails 테스트코드 프레임워크인 rspec에서는 expect와 with을 사용하면 됩니다. ( 링크 - Matching arguments )

RSpec.describe "#purchase" do
it "purchase log를 남긴다" do
purchase_event = {'product_id': 1, 'created_time': DateTime.now}
expect(CommerceController).to receive(:write_logging).with(purchase_evet)
post '/purchase'
end
end

이런 느낌 ㅎㅎㅎ


참고

[stack over flow] How to mock an external api in django?

Python Testing Documentation