Test Summary --python mock basic use

Content from the Internet revolution, summed up, especially for just learning to write mock baffle

What is the mock?

mock translation in analog means. mock here is to introduce a secondary unit module testing. It allows you to replace parts of your system with a mock object, and to assert the way they have been used.

mock Python2.x in a separate module, it is necessary to install separately.

> pip install -U mock

In Python3.x in the mock unittest has been integrated into the framework unit testing, so can be used directly.

  Maybe you and I first contact with the concept of time have some questions: the simulation to test things out so what test?

  But the project, the actual production is very complicated, when its unit tests, experience the following problems:

Dependent interface

The external interface call

The test environment is very complex

  Unit test is performed only for the current cell tests, all internal or external dependencies should be stable, have been tested elsewhere using mock can the external dependent components implemented simulation and replaced, so that the unit tests only focus on the function of the current unit.

Simple example

We'll start with the simplest example.

modular.py

#modular.py

class Count():

   def add(self):

       pass

To achieve this a class computing Count, add () method to achieve two numbers together. However, this feature I have not finished. Then you can make use of mock test it.

mock_demo01.py

from unittest import mock

import unittest

from modular import Count

# test Count class

class TestCount(unittest.TestCase):

   def test_add(self):

       count = Count()

       count.add = mock.Mock(return_value=13)

       result = count.add(8,5)

       self.assertEqual(result,13)

if __name__ == '__main__':

   unittest.main()

  count = Count()

  First, call the class being tested Count ().

  count.add = mock.Mock(return_value=7)

  Method is invoked by the simulation Mock class add () method returns the value, return_value defined add () method.

  result = count.add(2,5)

  Next, corresponding to normal call add () method, two transfer parameters 2 and 5, and 7 will be the result of the addition. Then, the result is that we 7 in the previous step to preset.

  self.assertEqual(result,7)

  Finally, () method asserted by assertEqual, whether the result returned is the expected result 7.

  Run the test results:

> python3 mock_demo01.py

----------------------------------------------------------------------

Ran 1 test in 0.000s

OK

Such a use case to complete the preparation with the help of the mock, and passed the test.

Complete functional test

   The next complete module.py file add () method.

#module.py

class Count():

   def add(self, a, b):

       return a + b

  Then, modify test cases:

from unittest import mock

import unittest

from module import Count

class MockDemo(unittest.TestCase):

   def test_add(self):

       count = Count()

       count.add = mock.Mock(return_value=13, side_effect=count.add)

       result = count.add(8, 8)

       print(result)

       count.add.assert_called_with(8, 8)

        self.assertEqual(result, 16)

if __name__ == '__main__':

   unittest.main()

   count.add =mock.Mock(return_value=13, side_effect=count.add)

  side_effect parameters and return_value is reversed. It is assigned to the mock results Alternatively, the cover return_value. Simply put, a simulated factory calls will return side_effect value instead return_value.

  Therefore, to set the parameter Count side_effect class add () method, the effect return_value failure.

  result = count.add(8, 8)

  print(result)

  This will be true calling add () method to obtain the return value of 16 (8 + 8). Print results by print.

  assert_called_with(8,8)

  Mock check whether the method to obtain the correct parameters.

Solving tests depend

    The previous example, just to let everyone have a preliminary mock impression. Followed, we look at how the mock-dependent method.

  For example, we want to test module A, then B calls A module depends on the module. However, due to the change of module B, resulting in the A module returns a result of changes, so that the test module A fails. In fact, for cases with module A, and A is the module, and there is no change, we should not fail fishes.

  This time is the mock play time. Mock off by the analog portion (B block) on the A module. As mock out portion (B block) should be tested by the use of other embodiments.

# function.py

def add_and_multiply(x, y):

   addition = x + y

   multiple = multiply(x, y)

   return (addition, multiple)

def multiply(x, y):

   return x * y

    Then, for add_and_multiply () function to write test cases. func_test.py

import unittest

import function

class MyTestCase(unittest.TestCase):


   def test_add_and_multiply(self):

       x = 3

       y = 5

       addition, multiple = function.add_and_multiply(x, y)

       self.assertEqual(8, addition)

       self.assertEqual(15, multiple)

if __name__ == "__main__":

   unittest.main()

 operation result:

> python3 func_test.py

----------------------------------------------------------------------

Ran 1 test in 0.000s

OK

  Currently running everything correctly often, however, add_and_multiply () function depend on the multiply () return value of the function. If this time modified multiply () function code.

……

def multiply(x, y):

   return x * y + 3

  This time, multiply the result returned by the function () becomes a plus 3 x * y.

  Run the test again:

> python3 func_test.py                                                   

F                                                                      

====================================================================== 

FAIL: test_add_and_multiply(__main__.MyTestCase)                      

---------------------------------------------------------------------- 

Traceback (most recent call last):                                     

 File "fun_test.py", line 19, in test_add_and_multiply                

   self.assertEqual(15, multiple)                                     

AssertionError: 15 != 18                                               


---------------------------------------------------------------------- 

Ran 1 test in 0.000s                                          

FAILED (failures=1)  

  Test run failed, however, add_and_multiply () function, and it does not make any changes to the test cases, the culprit is multiply () function caused, we should multiply () function mock out.

import unittest

from unittest.mock import patch

import function

class MyTestCase(unittest.TestCase):


   @patch("function.multiply")

   def test_add_and_multiply2(self, mock_multiply):

       x = 3

       y = 5

       mock_multiply.return_value = 15

       addition, multiple = function.add_and_multiply(x, y)

       mock_multiply.assert_called_once_with(3, 5)


       self.assertEqual(8, addition)

       self.assertEqual(15, multiple)

if __name__ == "__main__":

   unittest.main()

  @patch("function.multiply")

  Patch () Decorative / context manager can easily be simulated test class or object in the module. During the test, you specify the object will be replaced with an analog (or other objects), and reduction at the end of the test.

  Multiply this simulation function.py file () function.

  def test_add_and_multiply2(self, mock_multiply):

  Defining test cases, the mock the Multiply () function (object) rename mock_multiply objects.

  mock_multiply.return_value = 15

  The return value is set mock_multiply fixed object 15.

  ock_multiply.assert_called_once_with(3, 5)

  Ock_multiply parameter check method is correct.

  Again, run the test case by!

---------------------------------------------------

Guess you like

Origin blog.csdn.net/weixin_33831196/article/details/90981597