【发布时间】:2018-11-29 23:32:41
【问题描述】:
我正在使用 mockupdb 模块使用 Flask 的 REST 服务器(和 flask-pymongo)测试 MongoDB 作为 DB。我想在 json 请求中接收一个 DateTime,并将其存储为 Date 对象,以便将来使用此字段执行一些范围查询,因此,我将数据作为 EJSON (BSON) 发送以保持数据与我完全相同。
这是测试用例:
@pytest.fixture()
def client_and_mongoserver():
random.seed()
mongo_server = MockupDB(auto_ismaster=True, verbose=True)
mongo_server.run()
config = Config()
config.MONGO_URI = mongo_server.uri + '/test'
flask_app = create_app(config)
flask_app.testing = True
client = flask_app.test_client()
yield client, mongo_server
mongo_server.stop()
def test_insert(client_and_mongoserver):
client, server = client_and_mongoserver
headers = [('Content-Type', 'application/json')]
id = str(uuid.uuid4()).encode('utf-8')[:12]
now = datetime.now()
obj_id = ObjectId(id)
toInsert = {
"_id": obj_id,
"datetime": now
}
toVerify = {
"_id": obj_id,
"datetime": now
}
future = go(client.post, '/api/insert', data=dumps(toInsert), headers=headers)
request = server.receives(
OpMsg({
'insert': 'test',
'ordered': True,
'$db': "test",
'$readPreference': {"mode": "primary"},
'documents': [
toVerify
]
}, namespace='test')
)
request.ok(cursor={'inserted_id': id})
# act
http_response = future()
# assert
data = http_response.get_data(as_text=True)
这是端点。在插入调用之前,我将日期时间字符串转换为日期时间对象:
from flask_restful import Resource
from bson import json_util
class Insert(Resource):
def post(self):
if not request.json:
abort(400)
json_data = json_util.loads(request.data)
result = mongo.db.test.insert_one(json_data)
return {'message': 'OK'}, 200
但是测试生成了这个断言:
self = MockupDB(localhost, 37213)
args = (OpMsg({"insert": "test", "ordered": true, "$db": "test", "$readPreference": {"mode": "primary"}, "documents": [{"_id": {"$oid": "63343264363661622d393764"}, "datetime": {"$date": 1543493218306}}]}, namespace="test"),)
kwargs = {}, timeout = 10, end = 1543504028.309115
matcher = Matcher(OpMsg({"insert": "test", "ordered": true, "$db": "test", "$readPreference": {"mode": "primary"}, "documents": [{"_id": {"$oid": "63343264363661622d393764"}, "datetime": {"$date": 1543493218306}}]}, namespace="test"))
request = OpMsg({"insert": "test", "ordered": true, "$db": "test", "$readPreference": {"mode": "primary"}, "documents": [{"_id": {"$oid": "63343264363661622d393764"}, "datetime": {"$date": 1543493218306}}]}, namespace="test")
def receives(self, *args, **kwargs):
"""Pop the next `Request` and assert it matches.
Returns None if the server is stopped.
Pass a `Request` or request pattern to specify what client request to
expect. See the tutorial for examples. Pass ``timeout`` as a keyword
argument to override this server's ``request_timeout``.
"""
timeout = kwargs.pop('timeout', self._request_timeout)
end = time.time() + timeout
matcher = Matcher(*args, **kwargs)
while not self._stopped:
try:
# Short timeout so we notice if the server is stopped.
request = self._request_q.get(timeout=0.05)
except Empty:
if time.time() > end:
raise AssertionError('expected to receive %r, got nothing' % matcher.prototype)
else:
if matcher.matches(request):
return request
else:
raise AssertionError('expected to receive %r, got %r'
> % (matcher.prototype, request))
E AssertionError: expected to receive OpMsg({"insert": "test", "ordered": true, "$db": "test", "$readPreference": {"mode": "primary"}, "documents": [{"_id": {"$oid": "63343264363661622d393764"}, "datetime": {"$date": 1543493218306}}]}, namespace="test"), got OpMsg({"insert": "test", "ordered": true, "$db": "test", "$readPreference": {"mode": "primary"}, "documents": [{"_id": {"$oid": "63343264363661622d393764"}, "datetime": {"$date": 1543493218306}}]}, namespace="test")
.venv/lib/python3.6/site-packages/mockupdb/__init__.py:1291: AssertionError
值匹配但断言以任何一种方式提出。 如何使用烧瓶测试 Date 对象?
编辑: 正如@bauman.space 所指出的。不足:
'$db': 'test', # this key appears somewhere at the driver
'$readPreference': {"mode": "primary"}, # so does this one
不影响 mockupdb 进行的验证。我已经在其他测试用例中测试过了。
编辑 2:更改问题以防止混淆
【问题讨论】: