在单元测试中创建System.Web.Caching.Cache对象

时间:2008-10-28 18:17:33

标签: c# asp.net

我正在尝试为没有单元测试的项目中的函数实现单元测试,并且此函数需要System.Web.Caching.Cache对象作为参数。我一直试图通过使用代码来创建这个对象,如...

System.Web.Caching.Cache cache = new System.Web.Caching.Cache();
cache.Add(...);

...然后将'cache'作为参数传递,但Add()函数导致NullReferenceException。到目前为止,我最好的猜测是我不能在单元测试中创建这个缓存​​对象,需要从HttpContext.Current.Cache中检索它,我显然在单元测试中无法访问它。

如何对需要System.Web.Caching.Cache对象作为参数的函数进行单元测试?

4 个答案:

答案 0 :(得分:8)

当我遇到这类问题时(所讨论的类没有实现接口),我经常最终编写一个包含相关类的相关接口的包装器。然后我在我的代码中使用我的包装器。对于单元测试,我手工模拟包装器并将我自己的模拟对象插入其中。

当然,如果模拟框架有效,那么请使用它。我的经验是,所有模拟框架都存在各种.NET类的问题。

public interface ICacheWrapper
{
   ...methods to support
}

public class CacheWrapper : ICacheWrapper
{
    private System.Web.Caching.Cache cache;
    public CacheWrapper( System.Web.Caching.Cache cache )
    {
        this.cache = cache;
    }

    ... implement methods using cache ...
}

public class MockCacheWrapper : ICacheWrapper
{
    private MockCache cache;
    public MockCacheWrapper( MockCache cache )
    {
        this.cache = cache;
    }

    ... implement methods using mock cache...
}

public class MockCache
{
     ... implement ways to set mock values and retrieve them...
}

[Test]
public void CachingTest()
{
    ... set up omitted...

    ICacheWrapper wrapper = new MockCacheWrapper( new MockCache() );

    CacheManager manager = new CacheManager( wrapper );

    manager.Insert(item,value);

    Assert.AreEqual( value, manager[item] );
}

真实代码

...

CacheManager manager = new CacheManager( new CacheWrapper( HttpContext.Current.Cache ));

manager.Add(item,value);

...

答案 1 :(得分:2)

我认为你最好的选择是使用模拟对象(查看Rhino Mocks)。

答案 2 :(得分:1)

用于单元测试遗留代码的非常有用的工具是TypeMock Isolator。它将允许您完全绕过缓存对象,告诉它模拟该类以及您发现有问题的任何方法调用。与其他模拟框架不同,TypeMock使用反射拦截您告诉它为您模​​拟的方法调用,因此您不必处理繁琐的包装器。

TypeMock 商业产品,但它有开源项目的免费版本。他们使用拥有一个单一用户许可的“社区”版本,但我不知道是否仍然提供此版本。

答案 3 :(得分:0)

var httpResponse = MockRepository.GenerateMock<HttpResponseBase>();
var cache = MockRepository.GenerateMock<HttpCachePolicyBase>();
   cache.Stub(x => x.SetOmitVaryStar(true));
   httpResponse.Stub(x => x.Cache).Return(cache);
   httpContext.Stub(x => x.Response).Return(httpResponse);
   httpContext.Response.Stub(x => x.Cache).Return(cache);