deftest_add_user(self): """Ensure a new user can be added to the database.""" with self.client: response = self.client.post( '/users', data=json.dumps({ 'username': 'michael', 'email': 'michael@mherman.org' }), content_type='application/json', ) data = json.loads(response.data.decode()) self.assertEqual(response.status_code, 201) self.assertIn('michael@mherman.org was added!', data['message']) self.assertIn('success', data['status'])
运行测试,可以看到它是失败的:
$ docker-compose -f docker-compose-dev.yml run users python manage.py test
from project.api.models import User from project import db
运行测试。他们都应该通过:
Ran 5 tests in 0.092s
OK
那么错误和异常呢?类似:
不发送有效负载
负载无效 - 即JSON对象为空或包含错误的密钥
用户已存在于数据库中
添加一些测试:
deftest_add_user_invalid_json(self): """Ensure error is thrown if the JSON object is empty.""" with self.client: response = self.client.post( '/users', data=json.dumps({}), content_type='application/json', ) data = json.loads(response.data.decode()) self.assertEqual(response.status_code, 400) self.assertIn('Invalid payload.', data['message']) self.assertIn('fail', data['status'])
deftest_add_user_invalid_json_keys(self): """ Ensure error is thrown if the JSON object does not have a username key. """ with self.client: response = self.client.post( '/users', data=json.dumps({'email': 'michael@mherman.org'}), content_type='application/json', ) data = json.loads(response.data.decode()) self.assertEqual(response.status_code, 400) self.assertIn('Invalid payload.', data['message']) self.assertIn('fail', data['status'])
deftest_add_user_duplicate_email(self): """Ensure error is thrown if the email already exists.""" with self.client: self.client.post( '/users', data=json.dumps({ 'username': 'michael', 'email': 'michael@mherman.org' }), content_type='application/json', ) response = self.client.post( '/users', data=json.dumps({ 'username': 'michael', 'email': 'michael@mherman.org' }), content_type='application/json', ) data = json.loads(response.data.decode()) self.assertEqual(response.status_code, 400) self.assertIn( 'Sorry. That email already exists.', data['message']) self.assertIn('fail', data['status'])
from project import db from project.api.models import User
# ...
deftest_single_user(self): """Ensure get single user behaves correctly.""" user = User(username='michael', email='michael@mherman.org') db.session.add(user) db.session.commit() with self.client: response = self.client.get(f'/users/{user.id}') data = json.loads(response.data.decode()) self.assertEqual(response.status_code, 200) self.assertIn('michael', data['data']['username']) self.assertIn('michael@mherman.org', data['data']['email']) self.assertIn('success', data['status'])
在编写视图之前确保测试中断:
@users_blueprint.route('/users/<user_id>', methods=['GET']) defget_single_user(user_id): """Get single user details""" user = User.query.filter_by(id=user_id).first() response_object = { 'status': 'success', 'data': { 'id': user.id, 'username': user.username, 'email': user.email, 'active': user.active } } return jsonify(response_object), 200
测试应该通过。现在来看一些错误处理:
未提供 id
id 不存在
deftest_single_user_no_id(self): """Ensure error is thrown if an id is not provided.""" with self.client: response = self.client.get('/users/blah') data = json.loads(response.data.decode()) self.assertEqual(response.status_code, 404) self.assertIn('User does not exist', data['message']) self.assertIn('fail', data['status'])
deftest_single_user_incorrect_id(self): """Ensure error is thrown if the id does not exist.""" with self.client: response = self.client.get('/users/999') data = json.loads(response.data.decode()) self.assertEqual(response.status_code, 404) self.assertIn('User does not exist', data['message']) self.assertIn('fail', data['status'])
defadd_user(username, email): user = User(username=username, email=email) db.session.add(user) db.session.commit() return user
现在,重构 test_single_user() 测试,如下所示:
deftest_single_user(self): """Ensure get single user behaves correctly.""" user = add_user('michael', 'michael@mherman.org') with self.client: response = self.client.get(f'/users/{user.id}') data = json.loads(response.data.decode()) self.assertEqual(response.status_code, 200) self.assertIn('michael', data['data']['username']) self.assertIn('michael@mherman.org', data['data']['email']) self.assertIn('success', data['status'])
有了它,让我们添加新的测试:
deftest_all_users(self): """Ensure get all users behaves correctly.""" add_user('michael', 'michael@mherman.org') add_user('fletcher', 'fletcher@notreal.com') with self.client: response = self.client.get('/users') data = json.loads(response.data.decode()) self.assertEqual(response.status_code, 200) self.assertEqual(len(data['data']['users']), 2) self.assertIn('michael', data['data']['users'][0]['username']) self.assertIn( 'michael@mherman.org', data['data']['users'][0]['email']) self.assertIn('fletcher', data['data']['users'][1]['username']) self.assertIn( 'fletcher@notreal.com', data['data']['users'][1]['email']) self.assertIn('success', data['status'])
测试失败。然后添加视图:
@users_blueprint.route('/users', methods=['GET']) defget_all_users(): """Get all users""" response_object = { 'status': 'success', 'data': { 'users': [user.to_json() for user in User.query.all()] } } return jsonify(response_object), 200