我如何在python unittest模拟中使用side_effect测试除错误以外的错误?

时间:2019-04-29 20:15:05

标签: python-3.x flask patch python-unittest python-mock

我是一名初级开发人员,正在尝试为我们的API端点编写一些单元测试。以下是我正在测试的类以及运行时没有任何问题的实际测试。 (但是我仍然对它正在影响我的方法感到犹豫)。我的问题是如何通过使用python模拟的side_effects(或任何更好的建议)来改善测试,并确保它涵盖异常(在本例中为ValueError,SystemError,Exception)?我阅读了python模拟文档,但仍然想不出如何改进和重要地测试异常。

我们使用烧瓶微框架python3.x

---我正在测试的课程:

@USER_MOD.route('', methods=[HttpMethods.HTTP_POST])
@jwt_required
def create_user():
    """
    Private end point for creating users of the system
    :return: json
    """

    response = ""

    try:

        logger_obj.info("Request : POST : Create User: {} ".format(request.base_url))
        # validating input request
        if ValidationUtils.validate_request(request, "CREATE_USER"):
            logger_obj.debug("Request Validation Successful")
            response = UserService().create_new_user(request)
            logger_obj.debug("User Created: {} ".format(response))
            return jsonify(response), HTTPStatus.OK

    except ValueError as error:
        logger_obj.error("ValueError create_user() : {}".format(error))
        response = ApplicationUtils.create_api_response(status=ResponseConstants.MSG_ERROR, message=str(error))
        return jsonify(response), HTTPStatus.BAD_REQUEST
    except SystemError as error:
        logger_obj.error("SystemError create_user() : {}".format(error))
        response = ApplicationUtils.create_api_response(status=ResponseConstants.MSG_ERROR, message=str(error))
        return jsonify(response), HTTPStatus.INTERNAL_SERVER_ERROR
    except Exception as error:
        logger_obj.error("Exception create_user() : {}".format(error))
        response = ApplicationUtils.create_api_response(status=ResponseConstants.MSG_ERROR, message=str(error))
        return jsonify(response), HTTPStatus.UNAUTHORIZED
    finally:
        logger_obj.info("Response : POST : Create User: {} : {}".format(request.base_url, response))



--- Test for above class:

class UserApiTests(DataTestCase):  //(or i can use unittest.TestCase)

    def setUp(self):
        os.environ.update(self.config.to_env())
        self.flask_app = make_flask_app()
        self.client = self.flask_app.test_client()
        self.flask_app.testing = True

    @patch('usermgmt.app.services.user_service.UserService.create_new_user')
    def test_create_user(self, mock_create_new_user):

        # Given
        mock_create_new_user.return_value.status_code = 200

        mock_create_new_user.return_value = {
            "status": "SUCCESS"
        }
        data_to_post = {
            "name": "Test2",
            "email": "new-user2@entity.com",
            "entity_id": 1,
            "is_active": True,
            "product_roles": [
                {"product_id": 1, "role_id": 4},
                {"product_id": 2, "role_id": 4}
            ],
        }

        # When
        response = self.client.post('/api/usermgmt/users', data=json.dumps(data_to_post), headers={
            "Authorization": "Bearer {}".format(get_jwt(identity=self), "Content-Type: application/json")
        })

        data = response.data
        json_data = json.loads(data)

        # Then
        self.assertEqual(response.status_code, 200)
        self.assertEqual(json_data['status'], "SUCCESS")

1 个答案:

答案 0 :(得分:0)

在练习过程中,我发现这种方法非常好。

class TestCreateUser(TestCase):
    def test_works_in_correct_case(self):
        # equal to your test_create_user

    @patch("usermgmt.app.services.user_service.UserService.create_new_user")
    def test_handles_value_error_in_create_new_user(self, mock_create_new_user):
        mock_create_new_user.side_effect = ValueError

        # Your preparation flow here

        response = self.client.post('/api/usermgmt/users') # simplified call here is just an example
        self.assertEqual(response.status_code, 400)
        # check if response body is what you've expected, etc.