【问题标题】:How to Clear/Invalidate NDB Cache in Tests如何在测试中清除/无效 NDB 缓存
【发布时间】:2014-04-29 05:33:25
【问题描述】:

我有一个带有实例属性的简单NDB 模型,它不是NDB property。我想测试保存实体并从数据存储中检索时属性值是否丢失。

现在,当检索实体时,它与已放入数据存储区的实例相同。

有没有办法以编程方式清除/无效memcacheNDB 内存缓存

这个例子是一个pytest 测试,很抱歉。

from google.appengine.ext import testbed, ndb


class User(ndb.Model):
    name = ndb.TextProperty()
    foo = None


class TestNDBModel(object):

    def setup(self):
        self.testbed = testbed.Testbed()
        self.testbed.activate()
        self.testbed.init_datastore_v3_stub()
        self.testbed.init_memcache_stub()

    def teardown(self):
        self.testbed.deactivate()

    def test_foo(self):
        user = User(name='Andy')
        assert user.name == 'Andy'
        assert user.foo is None
        user.foo = 123
        assert user.foo == 123
        user_key = user.put()

        # Here I need to clear the cache somehow,
        # so that the entity must be retrieved from datastore

        retrieved_user = user_key.get()

        # These two will now fail
        assert retrieved_user is not user
        assert retrieved_user.foo is None

【问题讨论】:

    标签: python google-app-engine unit-testing caching app-engine-ndb


    【解决方案1】:

    您显然使用了错误的方法为retrieved_user 赋值。请改用以下内容:

    retrieved_user = user_key.delete(use_datastore=False)
    

    查看以下链接了解更多信息:

    https://developers.google.com/appengine/docs/python/ndb/functions#context_options

    【讨论】:

    • 这没有用,检索到的用户变为None,即使它是用User.get_by_id(user_key.id()) 获取的。不过,您提供的链接让我找到了实际的解决方案。
    【解决方案2】:

    解决方案是防止实体在使用entity.put(use_cache=False, use_memcache=False) 放入数据库时​​被缓存。

    from google.appengine.ext import testbed, ndb
    
    
    class User(ndb.Model):
        name = ndb.TextProperty()
        foo = None
    
    
    class TestNDBModel(object):
    
        def setup(self):
            self.testbed = testbed.Testbed()
            self.testbed.activate()
            self.testbed.init_datastore_v3_stub()
            self.testbed.init_memcache_stub()
    
        def teardown(self):
            self.testbed.deactivate()
    
        def test_foo(self):
            user = User(name='Andy')
            assert user.name == 'Andy'
            assert user.foo is None
            user.foo = 123
            assert user.foo == 123
    
            # This prevents the entity to be cached
            user_key = user.put(use_cache=False, use_memcache=False)
    
            # The entity is now retrieved from DB
            retrieved_user = user_key.get()
    
            # These two will now pass
            assert retrieved_user is not user
            assert retrieved_user.foo is None
    

    【讨论】:

      【解决方案3】:

      我遇到了同样的问题,正在寻找解决方案。这就是诀窍:

      ndb.get_context().clear_cache()
      

      【讨论】:

      • 这非常有用,因为我在野外运行时需要缓存和内存缓存,并且我的 put()put_multi() 方法在我正在测试的资源中被调用,而不是在测试本身中.从测试内部调用clear_cache() 可以让我保留真实代码,只控制测试平台。
      猜你喜欢
      • 1970-01-01
      • 2012-03-22
      • 2021-12-01
      • 1970-01-01
      • 1970-01-01
      • 2020-09-22
      • 2019-11-26
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多