【问题标题】:Testing with MemoryCache UpdateCallback使用 MemoryCache UpdateCallback 进行测试
【发布时间】:2014-12-04 04:37:07
【问题描述】:

以下测试间歇性地失败。它在 MemoryCache 中缓存一个具有绝对过期时间的项目,以及一个应该在删除项目之前调用的更新回调。然而,有时回调会在测试完成之前被调用,有时根本不会。

如果缓冲时间足够大,它将始终至少被调用一次。但这不符合我的目的,因为我要求缓存总是在数据过期之前尝试更新数据。

现在在我的真实世界场景中,我不会有 10 秒的过期时间和粒度,但我仍然担心这个测试间歇性地失败。

有人知道为什么会这样吗?

注意:60 秒到期和 5 秒缓冲也会间歇性失败。

using System;
using System.Runtime.Caching;
using System.Threading.Tasks;
using Microsoft.VisualStudio.TestTools.UnitTesting;

[TestClass]
public class MemoryCacheTest
{
    private const double ExpiryInSeconds = 10;
    private const double ExpiryBufferInSeconds = 5;

    private readonly object updateItemCounterLock = new object();
    private int updateItemCounter = 0;

    [TestMethod]
    public async Task MemoryCacheUpdateTest()
    {
        // Set item in cache with absolute expiration defined above
        MemoryCache cache = MemoryCache.Default;
        CacheItem cacheItem = new CacheItem("key", "value");
        CacheItemPolicy cacheItemPolicy = new CacheItemPolicy
        {
            AbsoluteExpiration = DateTimeOffset.Now + TimeSpan.FromSeconds(ExpiryInSeconds),
            UpdateCallback = new CacheEntryUpdateCallback(this.UpdateItem)
        };
        cache.Set(cacheItem, cacheItemPolicy);

        // Delay for absolute expiration time + buffer
        await Task.Delay(TimeSpan.FromSeconds(ExpiryInSeconds) + TimeSpan.FromSeconds(ExpiryBufferInSeconds));

        // Test that the update callback was invoked once
        Assert.AreEqual(1, updateItemCounter);
    }

    // Incrememnts the updateItemCounter
    private void UpdateItem(CacheEntryUpdateArguments args)
    {
        lock (updateItemCounterLock)
        {
            updateItemCounter++;
        }
    }
}

【问题讨论】:

  • 如果您注意到,AbsoluteExpiration 值表示该项目将被驱逐的时间量。这意味着它是保持有效的最短时间,而不是(具有讽刺意味的)绝对时间。这里的绝对是指它不是一个滑动的时间限制......并不是说它会在那个确切的时刻被驱逐。基本上,该项目可以在到期后的任何时间被驱逐,这可能是几秒钟,甚至几分钟后。我的测试表明,到期时间可能会在到期时间后 0 到 30 秒之间的任何时间发生,但可能会更长。
  • 这篇文章似乎表明内部实现有某种硬连线的 20 秒计时器:stackoverflow.com/questions/12630168/… 不确定这是否正确,但它肯定与我在我的测试结果。

标签: c# asp.net unit-testing caching memorycache


【解决方案1】:

我想调用 new CacheEntryUpdateCallback 是多余的。您可以致电: UpdateCallback = new CacheEntryUpdateCallback(this.UpdateItem) 代替

【讨论】:

    【解决方案2】:

    由于这个问题没有解决方案,我将我需要的 MemoryCache 方法抽象到一个接口中并针对它进行了测试。那时测试变得无效,因为我只是在测试我自己的接口实现。

    【讨论】:

      猜你喜欢
      • 2012-03-27
      • 2013-02-05
      • 2011-10-10
      • 2023-03-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多