Как вы издеваетесь над объектом кеширования в asp.net mvc? - PullRequest
17 голосов
/ 23 апреля 2009

Как бы я сменил объект кэширования на объекте ControllerContext для моих модульных тестов? Я попытался создать класс-оболочку, как показано ниже (поскольку объект кэша является запечатанным классом), но безуспешно.

var mockControllerContext = new Mock<ControllerContext>(); 
var mockhttpContext = new Mock<HttpContextBase>();            

mockhttpContext.SetupGet(o => o.Cache).Returns(
         new CacheWrapper(mockControllerContext.Object.HttpContext.Cache));

mockControllerContext.SetupGet(
                          o => o.HttpContext).Returns(mockhttpContext.Object);
this.tennisMatchupController.ControllerContext = mockControllerContext.Object; 

Ответы [ 4 ]

21 голосов
/ 24 апреля 2009

РЕДАКТИРОВАТЬ : я нашел более простой способ сделать это, по крайней мере, когда вы тестируете с пустым кешем. Используйте HttpRunTime.Cache в качестве возвращаемого значения для вашего ожидания в свойстве Cache HttpContext. Для более сложных сценариев использование оболочки и насмешек может быть лучшим способом справиться с этим - например, если вам нужно протестировать исключения из кэша.

var httpContext = MockRepository.GenerateMock<HttpContextBase>();
httpContext.Expect( h => h.Cache ).Return( HttpRunTime.Cache ).Repeat.Any()

Оригинал

Класс-обертка - это путь, но я думаю, что вы применяете его не в том месте. Я бы дал своему контроллеру свойство CacheWrapper, а затем создал конструктор, который позволил бы мне передать экземпляр CacheWrapper, в который можно установить это свойство. По умолчанию контроллер создает CacheWrapper с использованием HttpContext.Current.Cache. В вашем тестовом коде создайте фиктивный CacheWrapper для передачи в конструктор контроллера. Таким образом, вам вообще не нужно создавать фиктивный объект Cache - это сложно, потому что это запечатанный класс.

В качестве альтернативы, вы можете просто создать экземпляр класса Cache и вернуть его, поскольку для него есть открытый конструктор. Преимущество использования mock состоит в том, что вы можете проверить, что Cache используется через ожидания, поэтому я, вероятно, остановлюсь на обертке.

public class CacheWrapper
{
  private Cache Cache { get; set; }

  public CacheWrapper()
  {
     this.Cache = HttpContext.Current.Cache;
  }

  public virtual Object Add( string key,
                             Object value,
                             CacheDependency dependencies,
                             DateTime absoluteExpiration,
                             TimeSpan slidingExpiration,
                             CacheItemPriority priority,
                             CacheItemRemovedCallback onRemoveCallback )
  {
     this.Cache.Add( key,
                     value,
                     dependencies,
                     absoluteExpiration,
                     slidingExpiration,
                     priority,
                     onRemoveCallback );
  }

  ...wrap other methods...
}


public class BaseController : Controller
{
    private CacheWrapper { get; set; }

    public BaseController() : this(null) { }

    public BaseController( CacheWrapper cache )
    {
        this.CacheWrapper = cache ?? new CacheWrapper();
    }
}

[TestMethod]
public void CacheTest()
{
   var wrapper = MockRepository.GenerateMock<CacheWrapper>();

   wrapper.Expect( o => o.Add( ... ) ).Return( ... );

   var controller = new BaseController( wrapper );

   var result = controller.MyAction() as ViewResult;

   Assert.AreEqual( ... );

   wrapper.VerifyAllExpectations();
}
11 голосов
/ 30 июля 2013

Я бы порекомендовал использовать новый подход MemoryCache.Default от Microsoft. Вам нужно будет использовать .NET Framework 4.0 или более позднюю версию и включить ссылку на System.Runtime.Caching .

См. Статью здесь -> http://msdn.microsoft.com/en-us/library/dd997357(v=vs.100).aspx

MemoryCache.Default работает как для веб-приложений, так и для не веб-приложений. Поэтому идея заключается в том, чтобы обновить веб-приложение, чтобы удалить ссылки на HttpContext.Current.Cache и заменить их ссылками на MemoryCache.Default. Позже, когда вы решите провести модульное тестирование этих же методов, объект кэша все еще будет доступен и не будет иметь значение null. (Потому что он не зависит от HttpContext.)

Таким образом, вам даже не обязательно высмеивать компонент кэша.

5 голосов
/ 23 июля 2009
HttpContext.Current = new HttpContext(new HttpRequest(null, "http://tempuri.org", null), new HttpResponse(null));
0 голосов
/ 28 мая 2009

Вы можете попробовать использовать Typemock Isolator , он подделывает запечатанные классы из коробки, поэтому вам не понадобятся эти обертки.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...