2017-07-18 6 views
1

私はこれに似ているような状況があります。requests_mockを使用して正しいセッションが確実に呼び出されるようにするにはどうすればよいですか?

import unittest 
import requests_mock 
import requests 

import mock 

class ClassUnderTest: 
    def __init__(self): 
     self.session = requests.Session() 
     self.foo_url = 'http://google.com' 

    def do_foo(self): 
     return self.session.get(self.foo_url) 

    def do_foo_failing(self): 
     # I want to prevent accidentally doing this sort of operation 
     # instead of reusuing self.session 
     return requests.get(self.foo_url) 

を、私は、メソッドが正しく実行することを確認するには、だけでなく、私はself.sessionオブジェクトを使用しています確認してください。実際には同じセッションを再利用する代わりにrequests.getコールを誤って追加したため、この問題が発生しました。

しかし、これは、このようなテストは、実際にこの機能をテストしていない意味:

class TestClassUnderTest(unittest.TestCase): 

    @requests_mock.mock() 
    def test_do_foo_should_pass(self, m): 
     c = ClassUnderTest() 

     m.get('http://google.com', status_code=200) 
     r = c.do_foo() 

     self.assertEqual(200, r.status_code) 
     self.assertEqual(m.call_count, 1) 

    @requests_mock.mock() 
    def test_do_foo_should_fail(self, m): 
     c = ClassUnderTest() 
     m.get('http://google.com', status_code=200) 
     r = c.do_foo_failing() 

     self.assertEqual(200, r.status_code) 
     self.assertEqual(m.call_count, 1) 

私はモックでself.sessionの交換について考えているが、その後、私はまた、モックに設定STATUS_CODEようなことをしなければならない(と私の実際のコード例では、応答を消費するコードが正しく機能するように、モック.json() methodを追加する必要もあります)。

requests_mockを使用してself.session(この例ではrequests.getではない)だけを効果的に使用する方法がありますか?

答えて

0

それらの使用状況を追跡ラッパーで、MockClassにrequest.Sessionすべての機能をラップすることにより、次の作品:

class MockSession: 
    def __init__(self): 
     self.session = requests.Session() 
     self._called_methods = {} 

     def session_decorator(f): 
      def func(*args, **kwargs): 
       if f.__name__ not in self._called_methods: 
        self._called_methods[f.__name__] = 1 
       else: 
        self._called_methods[f.__name__] += 1 
       return f(*args, **kwargs) 
      return func 

     for name, f in inspect.getmembers(self.session): 
      if inspect.ismethod(f): 
      setattr(self, name, session_decorator(f)) 

このモックを使用した後、あなたがどのように頻繁に個々のメソッドをチェックする._called_methods値にアクセスすることができます呼び出されます。 requests_mockがどのように動作するのかは、実行時にこれを行う必要があることに注意してください(同様の機能を持つrequests.Sessionクラスを単純に拡張することによって、ロード時ではなく)。

class TestClassUnderTest(unittest.TestCase): 

    @requests_mock.mock() 
    def test_do_foo_should_pass(self, m): 
     c = ClassUnderTest() 
     c.session = MockSession() 
     m.get('http://google.com', status_code=200) 
     r = c.do_foo() 

     self.assertEqual(200, r.status_code) 
     self.assertEqual(m.call_count, 1) 
     self.assertEqual(c.session._called_count['GET'], 1) 

    @requests_mock.mock() 
    def test_do_foo_should_fail(self, m): 
     c = ClassUnderTest() 
     c.session = MockSession() 
     m.get('http://google.com', status_code=200) 
     r = c.do_foo_failing() 

     self.assertEqual(200, r.status_code) 
     self.assertEqual(m.call_count, 1) 

     # This will fail with an attribute error 
     # because that function was never invoked on the mock session 
     self.assertEqual(c.session._called_count['GET'], 1) 

にテストコードの結果を変更します

関連する問題