Python - create mock test for class method with context manager

I am trying to write a unit test for a function method of a class that has a context manager and many calls. I'm having a hard time figuring out how to properly mock the function so that I can check the return value. The class I'm trying to mock is db. As you can see below, I am using a patch, but I cannot figure out how to get it to return the correct method call. I am getting a generic mock function instead of the return value I am expecting.

db_class.py

import db

class Foo():
    def __init__(self):
        pass
    def method(self):
        with db.a() as a:
            b = a.b
            return b.fetch()

      

unit_db.py

 from mock import Mock, patch, MagicMock
 from db_class import Foo

 @patch('db_class.db')
 def test(db_mock):
     expected_result = [5,10]
     db_mock.return_value = Mock(__enter__ = db_mock,
                                 __exit___ = Mock(),
                                 b = Mock(fetch=expected_result))

     foo = Foo()
     result = foo.method()
     assert result == expected_result

      

+3


source to share


1 answer


Thanks to the commenters, I found a solution that works for me. The trick was to fix the correct class, in this case I wanted to install the db_class.db.a patch instead of db_class.db. After that, it's important to make sure the fetch () call is a method (I think I'm getting it right). The tricky part of this problem for me was fixing the right thing, and also working with the context manager, which requires a little extra intervention.



@patch('db_class.db.a')
def test(db_a):
    expected_result = [5,10]
    b_fetch = MagicMock()
    b_fetch.fetch.return_value = expected_result 
    db_a.return_value = Mock(b = b_fetch,
                         __enter__= db_a,
                         __exit__ =Mock())
    foo = Foo()
    result = foo.method()
    assert result == expected_result

if __name__ == "__main__":
    test()

      

+2


source







All Articles