未呼叫回呼

时间:2018-06-21 12:37:07

标签: c# .net unit-testing dependency-injection tdd

所以我有以下接口/方法的实现:

public class CacheService : ICacheService
{
    public T Get<T>(string cacheId, Func<T> getItemCallback) where T : class
    {
        var cacheExpiry = DateTime.UtcNow.AddMinutes(120);

        var item = HttpRuntime.Cache.Get(cacheId) as T;
        if (item == null)
        {
            item = getItemCallback();
            HttpRuntime.Cache.Insert(cacheId, item, null, cacheExpiry, Cache.NoSlidingExpiration);
        }
        return item;
    }
}

并且我正在尝试进行单元测试(NUnit / Moq),该测试给出了一个空缓存(类型为Whatever)

<Whatever> Callback

回调被调用一次;给定Cache服务的模拟实例以及包含回调的服务。

方法的真实主体看起来像这样

return _services.Cache.GetBy("CacheKey", () => Callback("argumentsHere"));

但是发生的是它拒绝调用回调(如果我这样做,则通过测试通过测试)

return Callback("argumentsHere");

p.s。我像这样设置测试

ICacheService cache = null;
_mockDomainServiceProvider.Setup(x => x.Cache).Returns(cache);

但是如果我改为使用“真实的” CacheService进行设置

ICacheService cache = new CacheService();
_mockDomainServiceProvider.Setup(x => x.Cache).Returns(cache);

它可以工作,但是更多的是集成测试吗?

1 个答案:

答案 0 :(得分:1)

我还没有使用过模拟,所以不知道模拟时它如何处理参数的来龙去脉,但是您可以执行类似的操作来解决问题。

public class CacheService : ICacheService
{
    public T Get<T>(string cacheId, Func<T> getItemCallback) where T : class
    {
        var cacheExpiry = DateTime.UtcNow.AddMinutes(120);

        var item = HttpRuntime.Cache.Get(cacheId) as T;
        if (item == null)
        {
            item = getItemCallback();
            HttpRuntime.Cache.Insert(cacheId, item, null, cacheExpiry, Cache.NoSlidingExpiration);
        }
        return item;
    }

    protected virtual InsertCache(string key, Object value, CacheDependency dependencies, 
                           DateTime absoluteExpiration, TimeSpan slidingExpiration) {
        HttpRuntime.Cache.Insert(key, value, dependencies, absoluteExpiration, 
                     Cache.slidingExpiration);
    }
}

对调用进行同样的操作以获取cacheExpiry和Item,现在在您的测试中,您可以创建一个MockCacheService,该MockCacheService使用用于从覆盖的受保护函数返回cacheExpiry和item的公共属性来覆盖CacheService。现在,您已经完全控制了依赖项。这是给猫剥皮的另一种方式。