I have the following structure:
ClassB():
def foo():
Class A():
def __init__(self, B):
#some initialisations
def method1():
#complex logic
B.foo()
I am trying to write a unit test method1 and would like to test if foo is called once or not. How I can achieve this? What should I mock?
Based on the further information provided by OP, a rework on the answer was done.
The code below has been tested locally with Python3.8.3 on CentOS 8. Run python3 -m unittest
to see the test result.
Functional code(sub.py):
class B():
def foo(self):
pass
class A():
def __init__(self, B):
self.b = B
def method1(self):
self.b.foo()
Test code(test.py):
from unittest import TestCase
from unittest.mock import patch
from sub import A, B
class Test(TestCase):
def test_A(self):
with patch('sub.B.foo') as mock_foo:
a = A(B)
a.method1()
mock_foo.assert_called_once()
Basically the test code tries to mock the B.foo
method and checks if the method has been called EXACTLY ONCE when A.method1
is invoked.
a = A(B)
line does not call B.foo
a.method1()
line calls B.foo
In total, B.foo
is called exactly once so mock_foo.assert_called_once()
will pass. If any of the arguments above turns out to be invalid, the assertion will fail. In case you just need to check that B.foo
has been called at least once, use mock_foo.assert_called()
instead.
For details of the mock system, I suggest to read the official docs .
You should create a Mock for B
, pass it to the constructor of A
and check if the function was called once.
You can write the Mock by yourself. Eg:
class B_Mock():
def __init__(self):
self.foo_calls = 0
def foo(self):
self.foo_calls += 1
And than check the attr foo_calls
of your B_Mock instance with assert
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.