使用Flask和Mockupdb(MongoDB)测试DateTime对象

时间:2018-11-22 19:05:32

标签: flask pymongo

我正在使用模拟数据库模块使用Flask的REST服务器(和flask-pymongo)将MongoDB作为数据库进行测试。我想在json请求中接收DateTime,并将其存储为Date对象,以便将来使用此字段执行一些范围查询,因此,我将数据作为EJSON(BSON)发送,以使数据与I完全相同。 / p>

这是测试用例:

@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)

这是端点。在插入调用之前,我将datetime字符串转换为datetime对象:

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

值匹配,但是以任何一种方式引发断言。 如何使用Flask测试Date对象?

编辑: 正如@ bauman.space所指出的。缺乏:

'$db': 'test',  # this key appears somewhere at the driver 
'$readPreference': {"mode": "primary"},  # so does this one

不影响嘲笑模型的验证。我已经在其他测试案例中进行了测试。

编辑2:更改问题以防止混淆

1 个答案:

答案 0 :(得分:0)

您的断言颇具描述性

AssertionError: 
expected to receive 
OpMsg(
    {"insert": "test", 
     "ordered": true, 
     "documents": [{"_id": "a3dbe8a7e1cc43469b706a8877b0a14a", 
                    "datetime": {"$date": 1542901445120}}]
     }, namespace="test"
), 
got 
OpMsg(
    {"insert": "test", 
     "ordered": true, 
     "$db": "test", 
     "$readPreference": {"mode": "primary"}, 
     "documents": [{"_id": "a3dbe8a7e1cc43469b706a8877b0a14a", 
                    "datetime": {"$date": 1542901445120}}]
    }, namespace="test")

看起来您只需要在验证代码中包括一些标准的MongoDB密钥即可。

用这个交换您的内容并尝试一下?

request = server.receives(
    OpMsg({
        'insert': 'test',
        'ordered': True,
        '$db': 'test',  # this key appears somewhere at the driver 
        '$readPreference': {"mode": "primary"},  # so does this one
        'documents': [
            toVerify
        ]
    }, namespace='test')
)