Saya memiliki fungsi ( foo
) yang memanggil fungsi lain ( bar
). Jika pemanggilan bar()
memunculkan sebuah HttpError
, saya ingin menanganinya secara khusus jika kode statusnya adalah 404, jika tidak, naikkan kembali.
Saya mencoba untuk menulis beberapa pengujian unit seputar foo
fungsi ini , mengejek panggilan ke bar()
. Sayangnya, saya tidak bisa mendapatkan panggilan yang diejek bar()
untuk mengajukan Pengecualian yang tertangkap oleh except
blokir saya .
Inilah kode saya yang menggambarkan masalah saya:
import unittest
import mock
from apiclient.errors import HttpError
class FooTests(unittest.TestCase):
@mock.patch('my_tests.bar')
def test_foo_shouldReturnResultOfBar_whenBarSucceeds(self, barMock):
barMock.return_value = True
result = foo()
self.assertTrue(result) # passes
@mock.patch('my_tests.bar')
def test_foo_shouldReturnNone_whenBarRaiseHttpError404(self, barMock):
barMock.side_effect = HttpError(mock.Mock(return_value={'status': 404}), 'not found')
result = foo()
self.assertIsNone(result) # fails, test raises HttpError
@mock.patch('my_tests.bar')
def test_foo_shouldRaiseHttpError_whenBarRaiseHttpErrorNot404(self, barMock):
barMock.side_effect = HttpError(mock.Mock(return_value={'status': 500}), 'error')
with self.assertRaises(HttpError): # passes
foo()
def foo():
try:
result = bar()
return result
except HttpError as error:
if error.resp.status == 404:
print '404 - %s' % error.message
return None
raise
def bar():
raise NotImplementedError()
Aku mengikuti docs Mock yang mengatakan bahwa Anda harus mengatur side_effect
dari Mock
contoh ke Exception
kelas untuk memiliki fungsi mengejek kenaikan gaji kesalahan.
Saya juga melihat beberapa Tanya Jawab StackOverflow terkait lainnya, dan sepertinya saya melakukan hal yang sama yang mereka lakukan untuk menyebabkan dan Pengecualian dimunculkan oleh tiruan mereka.
- https://stackoverflow.com/a/10310532/346561
- Cara menggunakan Python Mock untuk memunculkan pengecualian - tetapi dengan Errno disetel ke nilai tertentu
Mengapa pengaturan side_effect
dari barMock
tidak menyebabkan diharapkan Exception
akan dibangkitkan? Jika saya melakukan sesuatu yang aneh, bagaimana saya harus menguji logika di except
blok saya ?
sumber
resp.status
kode di sana. Dari manaHTTPError
asalnyaHttpError
adalah kelas yang ditentukan di lib Googleapiclient
yang kami gunakan di GAE. Ini__init__
didefinisikan dengan params(resp, content)
jadi saya mencoba membuat contoh tiruan untuk respons, dengan kode status yang sesuai ditentukan.return_value
;resp
tidak dipanggil .HttpError
dan sebaliknya mencoba hanya menggunakanException
contoh biasa . Ini bekerja dengan sempurna. Artinya, ini pasti ada hubungannya dengan cara saya mengonfigurasiHttpError
instance, mungkin terkait dengan cara saya membuatMock
instance untuk respons.Jawaban:
Tiruan Anda meningkatkan pengecualian dengan baik, tetapi
error.resp.status
nilainya hilang. Daripada menggunakanreturn_value
, cukup beri tahuMock
bahwa itustatus
adalah atribut:Argumen kata kunci tambahan untuk
Mock()
ditetapkan sebagai atribut pada objek yang dihasilkan.Saya meletakkan definisi
foo
dan Andabar
dalam sebuahmy_tests
modul, ditambahkan diHttpError
kelas sehingga saya dapat menggunakannya juga, dan pengujian Anda kemudian dapat dijalankan hingga berhasil:Anda bahkan dapat melihat
print '404 - %s' % error.message
baris tersebut dijalankan, tetapi saya pikir Anda ingin menggunakannya dierror.content
sana; itulahHttpError()
set atribut dari argumen kedua, bagaimanapun juga.sumber
side_effect
adalah bagian kuncinya