【问题标题】:How to test DateTimeProperty in App Engine NDB?如何在 App Engine NDB 中测试 DateTimeProperty?
【发布时间】:2012-10-23 06:55:10
【问题描述】:

我正在尝试使用 App Engine 的 NDB 测试 DateTimeProperty 的过滤器,但我已将其设置为 auto_now?

有没有办法绕过这个进行单元测试?

例子:

class MyModel(ndb.Model)
  timestamp = ndb.DateTimeProperty(auto_now)
  name = ndb.StringProperty()


def testMyModelFilter(self):
  test1 = MyModel()
  test1.timestamp = datetime.datetime.now() - datetime.timedelta(hours=2)
  test1.put()
  test2 = MyModel()
  test2.timestamp = datetime.datetime.now() - datetime.timedelta(hours=1)
  test2.put()

  hour_ago = datetime.datetime.now() - datetime.timedelta(hours=1)
  fetched = MyModel.query().filter(MyModel.timestamp < hour_ago).fetch(
      None, keys_only=True)

不幸的是,当我使用 test.put() 将其提交到数据存储区时,它使用的是 put() 的时间。

【问题讨论】:

  • 一些想法:覆盖 _pre_put_hook() 或将 MyModel.timestamp 设置为正常的 ndb.DateTimeProperty(如果您正在进行测试)。
  • 主要问题是因为它正在记录不同的时间戳,并且您正在寻找一种方法来过滤该确切时间以验证您的过滤器是否有效?也就是说,将test.put()的结果赋值给test_key,然后通过key获取实体就可以了吗?
  • @RocketDonkey 是的,我正在寻找验证我的过滤器。我已经扩展了我的示例以包含查找。

标签: python google-app-engine app-engine-ndb


【解决方案1】:

所以您可以尝试的一件事(正如@mjibson 所暗示的)是在测试期间覆盖您的模型。由于MyModel 本身是一个对象,您可以将timestamp_auto_now 属性修改为False 以进行测试。例如:

def testMyModelFilter(self):
  # Change the auto_now parameter to False
  MyModel.timestamp._auto_now = False

  # Test as usual...
  test1 = MyModel()
  test1.timestamp = datetime.datetime.now() - datetime.timedelta(hours=2)
  test1.put()
  test2 = MyModel()
  test2.timestamp = datetime.datetime.now() - datetime.timedelta(hours=1)
  test2.put()

  hour_ago = datetime.datetime.now() - datetime.timedelta(hours=1)
  fetched = MyModel.query().filter(MyModel.timestamp < hour_ago).fetch(
      None, keys_only=True)

我记得在其他地方看到过这种技术,所以如果我能找到它,我会链接(如果它有效,当然:))。

【讨论】:

  • 我必须使用 dict 还是可以覆盖参数? MyModel.timestamp = ndb.DateTimeProperty(auto_now=False)
  • @wag2639 我可能是错的(它快到我的就寝时间了,所以我可能是),但我认为这会弄乱模型属性函数的方式(GAE 模型使用描述符类,它们背后都有自己的特点)。但是,您确实发现了一个稍微好一点的版本,我现在将其发布:)
  • @wag2639 更具体地说,如果您在尝试将 ndb.DateTimeProperty 重新分配之前的评论之前比较 dir(MyModel.timestamp) 与分配后的值,您会发现它缺少 @ 987654327@ 参数,这是您的 MyModel 类引用的存储位置。
  • 虽然这应该可以,但在我的测试中仍然失败。我目前的工作只是不使用 auto_now 选项并在使用类方法创建实体时手动设置它。如果它们位于 2 个单独的文件/模块(models.py 和 models_test.py)中,是否会影响测试?
  • @wag2639 好的,还有一件事。我忘记了 NDB 模型具有不同的底层结构(这应该很明显,我的错) - 尝试使用 MyModel.timestamp._auto_now = Falseauto_now 现在是一个私有变量)。我只是在本地运行了一些模拟您的结构的简单测试,它似乎可以工作,所以如果它仍然关闭,请告诉我,我们可以找到调整它的方法。
猜你喜欢
  • 1970-01-01
  • 2011-04-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-07-01
相关资源
最近更新 更多