Python interface to automate the use of mock basic module

mock Profile

After python3 mock unittest module has been integrated into the framework of the test, then no separate installation

A mock Mock word meaning in English, so we can guess that the main function of the library is to simulate some things

To be exact, Mock is a Python library for unit testing support, and its main function is to replace the use of mock objects out of the specified Python objects to achieve the mock object's behavior

Since the mock has been integrated into a unittest unit testing framework, we can imagine the purpose of the mock is to make us better test

mock role

1. The resolution of dependencies: When we test a function module interface or when, or if this interface function modules rely on other interfaces or other modules, so if rely interface or function module is not developed, then we can

Using mock analog is dependent interfaces, interfaces to complete certain tests

2. Unit Testing: If a function is not developed, we have to be written in the code test cases, we can simulate this function to be tested

3. simulate complex business interfaces: to simulate the actual work if we tested an interface function, if this interface is dependent on a very complex interface business, then we can use this mock complex business interface, in fact,

This is dependent on the interface and solve the same principle

4. The front and rear ends of the FBI: If you are a front page development, now need to develop a function: according to the state returned backstage to show a different page, then you need to call back interface, the interface has not been developed but the background is not you

This part of the work to stop it? The answer is no, you can simulate the background to the aid of mock this interface returns the data you want

mock installation

python mock module 3 have been integrated into a unittest framework, so when you only need to use unittest import mock at the beginning of the file can be imported from

If you are using python2 then you need to perform pip install mock installation can then import mock

mock examples

How not to develop a complete functional test?

If there are now two numbers together to achieve a functional need to write test cases, but due to the slow progress of the development, take only two simple framework, and no internal implementation

 

"""
------------------------------------
@Time : 2019/6/26 14:09
@Auth : linux超
@File : ClassFunc.py
@IDE  : PyCharm
@Motto: Real warriors,dare to face the bleak warning,dare to face the incisive error!
@QQ  : [email protected]
@GROUP: 878565760
------------------------------------
"""
import unittest
from unittest import mock


class SubClass(object):
    def add(self, a, b):
        """两个数相加"""
        pass

the TestSub class (of unittest.TestCase):
  "" "Test Example two numbers together with" ""
    DEF test_sub (Self):
        Sub = SubClass () function # test class instance initialization
        sub.add = mock.Mock (return_value = 10 ) # mock add method returns 10
        result sub.add = (. 5,. 5) # call function test
        self.assertEqual (result, 10) # assertions expected results and the actual results


if __name__ == '__main__':
    unittest.main()

 

Test Results

 

.
----------------------------------------------------------------------
Ran 1 test in 0.000s

OK

Process finished with exit code

 

The test results showed that the test case has been executed by

Indeed the principle of simulated mock add method is to use the same method for receiving a mock target object (using sub.add received), then the object is invoked when the mock (sub.add ()) returns the parameter data corresponding return_value

As a result, the surface looks is to simulate the add method (this is just my personal understanding, and do not ignore)

You can do an experiment, the use cases add other names, too, can be changed by the test

ok, continue

We finished writing use cases, but also to develop the functional development since finished (squalling do you want to?), Since the real functions already tested, then how do we direct test cases on the basis of real functions on top of it?

How complete functional test?

We use the code example of the slightly modified

 

"""
------------------------------------
@Time : 2019/6/26 14:09
@Auth : linux超
@File : ClassFunc.py
@IDE  : PyCharm
@Motto: Real warriors,dare to face the bleak warning,dare to face the incisive error!
@QQ  : [email protected]
@GROUP: 878565760
------------------------------------
"""
import unittest
from unittest import mock


class SubClass(object):
    def add(self, a, b):
        """两个数相加"""
        return a + b

the TestSub class (of unittest.TestCase):
    "" "Test two numbers" ""
    DEF test_sub (Self):
        Sub = SubClass () function # test class instance initialization
        sub.add = mock.Mock (return_value = 10, side_effect = sub.add) # pass side_effect keyword parameters, parameter values override return_value, add method using real test
        result = sub.add (5, 11) # real test function call
        self.assertEqual (result, 16) # assert actual results and expected results


if __name__ == '__main__':
    unittest.main()

 

side_effect parameters

Mock the code we give way to add another keyword argument side_effect = sub.add, this parameter and return_value the contrary, when the passing of this parameter return_value parameters will fail

And side_effect into effect, I give the parameter value here is equivalent to add sub.add method of address, when you call the add method will add real use of the method, also reached add the actual methods we tested.

You will also be understood that when passing a side_effect measured parameters with the value in address, mock will not work

side_effect receiving an iterative sequence is, when a plurality of transmission values ​​will return different values ​​then each call mock

 

mock_obj = mock.Mock(side_effect= [1,2,3])
print(mock_obj())
print(mock_obj())
print(mock_obj())
print(mock_obj())

输出
Traceback (most recent call last):
1
  File "D:/MyThreading/mymock.py", line 37, in <module>
2
    print(mock_obj())
3
  File "C:\Python36\lib\unittest\mock.py", line 939, in __call__
    return _mock_self._mock_call(*args, **kwargs)
  File "C:\Python36\lib\unittest\mock.py", line 998, in _mock_call
    result = next(effect)
StopIteration

Process finished with exit code 1

 

When (the principle of the place is somewhat similar to generator) are all values ​​will be taken after an error

How dependencies of functional tests?

Consider a scenario: we want to test a payment interface but the payment interface in turn depends on a third-party payment interface, third-party payment interface we do not have permission to use, then how do we test our own this interface it?

See examples below

If the third party interfaces and our own payment interface as follows

 

"""
------------------------------------
@Time : 2019/6/26 15:09
@Auth : linux超
@File : PayMent.py
@IDE  : PyCharm
@Motto: Real warriors,dare to face the bleak warning,dare to face the incisive error!
@QQ  : [email protected]
@GROUP: 878565760
------------------------------------
"""
import requests


class PayApi(object):

    @staticmethod
    DEF auth (Card, AMOUNT):
        "" "
        third-party payment gateway
        : param card: Card
        : param amount: Amount paid
        : return:
        " ""
        pay_url = "http://www.zhifubao.com" third party # payment Gateway address
        Data = { "Card": Card, "AMOUNT": AMOUNT}
        Response = requests.post (pay_url, Data = Data) # interface to third-party payment request
        return response # return a status code

    the Pay DEF (Self, user_id, Card, AMOUNT):
        "" "
        Our own payment interface
        : param user_id: user the above mentioned id
        : param Card: Card
        : param amount: Amount paid
        : return:
        " ""
     # call the third-party payment interface
        response self.auth = (Card, aMOUNT)
        the try:
            IF Response [ 'status_code'] == '200 is':
                Print ( 'user {} {} successful payment amount' .format (user_id, aMOUNT))
                return 'successful payment'
            elif Response [ 'status_code'] == '500':
                Print ( '{} user fails to pay, the amount of change' .format (user_id))
                return 'payment fails'
            the else:
                return 'unknown error'
        the except Exception:
            return "Error, Server abnormal!"


if __name__ == '__main__':
    pass

 

It is clear that the third party payment interface is not accessible because the address of the interface is my DIY, in order to simulate the actual third-party payment interface we can not use

Write test cases

 

"""
------------------------------------
@Time : 2019/6/26 15:22
@Auth : linux超
@File : testpay.py
@IDE  : PyCharm
@Motto: Real warriors,dare to face the bleak warning,dare to face the incisive error!
@QQ  : [email protected]
@GROUP: 878565760
------------------------------------
"""
import unittest
from unittest import mock

from payment.PayMent import PayApi


class TestPayApi(unittest.TestCase):

    def test_success(self):
        pay = PayApi()
        pay.auth = mock.Mock(return_value={'status_code':'200'})
        status = pay.pay('1000', '12345', '10000')
        self.assertEqual(status, '支付成功')

    def test_fail(self):
        pay = PayApi()
        pay.auth = mock.Mock(return_value={'status_code':'500'})
        status = pay.pay('1000', '12345', '10000')
        self.assertEqual(status, '支付失败')

    def test_error(self):
        pay = PayApi()
        pay.auth = mock.Mock(return_value={'status_code':'300'})
        status = pay.pay('1000', '12345', '10000')
        self.assertEqual(status, '未知错误')

    def test_exception(self):
        pay = PayApi()
        pay.auth = mock.Mock(return_value='200')
        status = pay.pay('1000', '12345', '10000')
        self.assertEqual(status, 'Error, 服务器异常!')


if __name__ == '__main__':
    unittest.main()

 

Test output

 

1000 .... user fails to pay, the same amount of
user payment amount 10 000 1000 success

----------------------------------------------------------------------
Ran 4 tests in 0.001s

OK

Process finished with exit code 0

 

As can be seen from the results, even if the third-party payment interface can not be used, but we still own payment interface test passed

Some people might ask, do not use third-party payment, whether our test results are valid it?

Usually we test a module, we can consider other functional modules is normal, only for the goal to test module is no problem, so that the test result is correct

In fact, the above code can also use another way to write

The method of mock objects

 

"""
------------------------------------
@Time : 2019/6/26 15:22
@Auth : linux超
@File : testpay.py
@IDE  : PyCharm
@Motto: Real warriors,dare to face the bleak warning,dare to face the incisive error!
@QQ  : [email protected]
@GROUP: 878565760
------------------------------------
"""
import unittest
from unittest import mock
from unittest.mock import patch

from payment.PayMent import PayApi


class TestPayApi(unittest.TestCase):

    def setUp(self):
        self.pay = PayApi()

    @patch.object(PayApi, 'auth')
    def test_success(self, mock_auth):

        mock_auth.return_value = {'status_code':'200'}
        status = self.pay.pay('1000', '12345', '10000')
        self.assertEqual(status, '支付成功')

    @patch.object(PayApi, 'auth')
    def test_fail(self, mock_auth):
        mock_auth.return_value={'status_code':'500'}
        status = self.pay.pay('1000', '12345', '10000')
        self.assertEqual(status, '支付失败')

    @patch.object(PayApi, 'auth')
    def test_error(self, mock_auth):
        mock_auth.return_value={'status_code':'300'}
        status = self.pay.pay('1000', '12345', '10000')
        self.assertEqual(status, '未知错误')

    @patch.object(PayApi, 'auth')
    def test_exception(self, mock_auth):
        mock_auth.return_value='200'
        status = self.pay.pay('1000', '12345', '10000')
        self.assertEqual(status, 'Error, 服务器异常!')


if __name__ == '__main__':
    unittest.main()

 

There mock an ordinary function, a plurality of mock method, where the first is not to say, the above examples, and similar wording

At last

There are many built-in functions mock method

And mock function is very powerful, is not able to finish a sentence or two, this article introduces the basic use of mock, is very simple, to practice how to apply, how to master the more powerful methods need to slowly grope

Guess you like

Origin www.linuxidc.com/Linux/2019-08/160338.htm