2012-04-30 41 views
7

Tôi đang viết một số bài kiểm tra đơn vị và tự hỏi liệu nó có thuận lợi để giả lập Cache và nếu có, làm thế nào?Mocking System.Web.Caching.Cache - Mock hoặc kiểm tra null?

Hiện nay trong các thử nghiệm của tôi, tôi đang chế giễu ra HttpContextBase và gói nó trong một tùy chỉnh HttpContextFactory:

var mockedHttpContextBase = new Mock<HttpContextBase>(); 

IHttpContextFactory httpContextFactory = new HttpContextFactory 
{ 
    Current = mockedHttpContextBase.Object 
}; 

và khi mã của tôi tiêu thụ một IHttpContextFactory tôi kiểm tra xem bộ nhớ cache là null trước khi làm bất cứ điều gì với nó.

var cache = _httpContextFactory.Current.Cache; 

Func<SomeReturnType> doSomeWork =() => _foo.someMethodIExecute(param1,param2); 

return cache != null ? cache.GetOrStore("doSomeWorkCacheKey",doSomeWork, 900) 
        : doSomeWork.Invoke(); 

Có quyền kiểm tra bộ nhớ cache bị rỗng như thế này mỗi khi tôi sử dụng hoặc thử giả lập bộ nhớ cache trong thử nghiệm sao cho nó không rỗng khi chạy thử nghiệm đơn vị của bạn?

Trả lời

3

Nếu mã của bạn giả bộ nhớ cache có thể null và thực hiện kiểm tra trước khi truy cập nó (như nó bây giờ), bạn cần phải có hai bài kiểm tra đơn vị cho mỗi truy cập bộ nhớ cache:

  • bộ nhớ cache tồn tại và mục là lưu trữ và lấy ra (kiểm tra GetOrStore cuộc gọi)
  • bộ nhớ cache là null và bạn chỉ đơn giản là khẳng định đại biểu gọi

Nếu đây là mô hình phổ biến (kiểm tra null), thay vì có hai bài kiểm tra mỗi lần phụ thuộc vào bộ nhớ cache là bắt buộc, tôi đề nghị gói nó vào Null Object Pattern và thử nghiệm một lần và sau đó chỉ cần sử dụng NOP làm phụ thuộc có thể được mô phỏng.

Sửa: cache "chế giễu" dụ

var cache = new Cache(); 
// Add takes more parameters; fill whatever is necessary to make it work 
cache.Add("doSomeWorkCacheKey", doSomeWork, ...); 
var mockedHttpContextBase = new Mock<HttpContextBase>(); 
// tell your mock to return pre-configured cache 
mockedHttpContextBase.Setup(m => m.Cache).Returns(cache); 

IHttpContextFactory httpContextFactory = new HttpContextFactory 
{ 
    Current = mockedHttpContextBase.Object 
}; 
+0

Cảm ơn Jimmy. Đối với điểm 1, làm thế nào bạn sẽ viết một bài kiểm tra mà phụ thuộc vào bộ nhớ cache tồn tại? Làm thế nào bạn sẽ giả bộ nhớ cache trong trường hợp này để thực hiện thử nghiệm? –

+0

@JamieDixon: bạn có thể không thực sự giả lập 'Cache' vì nó được niêm phong; bạn sẽ phải cấu hình trước nó bằng cách sử dụng thực hiện 'Cache' thực và làm cho' HttpContextBase' của bạn trở lại chế độ cache đã cấu hình sẵn khi được yêu cầu. Tôi đã thêm ví dụ vào bài đăng của mình. –

+0

Cảm ơn Jimmy lần nữa. Tôi đánh giá cao thời gian và sự giúp đỡ của bạn. Tôi đã tự thêm câu trả lời sau khi tìm kiếm thêm. Tôi dường như sử dụng 'HttpRuntime.Cache' là thích hợp hơn vì nó sẽ khởi tạo mọi thứ cần thiết để làm việc khi' System.Web.Caching.Cache' sẽ ném 'NullReferenceExeption' nếu mọi thứ không được cấu hình. –

13

Sau một chút tìm kiếm có vẻ như rằng tôi có thể sử dụng HttpRuntime.Cache thay vì System.Web.Caching.Cache khi viết bài kiểm tra đơn vị của tôi.

như vậy mà:

var mockedHttpContextBase = new Mock<HttpContextBase>(); mockedHttpContextBase.Setup(m => m.Cache).Returns(HttpRuntime.Cache);

Bộ nhớ cache không bao giờ được null (nó sẽ là một ngoại lệ thích hợp nếu nó đã được) để tôi có thể loại bỏ các tham chiếu null kiểm tra từ mã của tôi.

+0

Tốt di chuyển sidestepping unMoq'able kín System.Web.Caching.Cache với HttpRuntime.Cache – BozoJoe

+0

Điều này đã không làm việc cho tôi bởi vì các bài kiểm tra của tôi là không đồng bộ. Do đó, trạng thái chia sẻ 'HttpRuntime.Cache' và không phải cho mỗi thử nghiệm. Nó hoạt động khi chạy thử nghiệm riêng lẻ. –

+0

Để rõ ràng - bạn không khởi tạo bộ nhớ cache trong trường hợp này. Chỉ cần thêm các mục của bạn vào HttpRuntime.Cache trước khi sử dụng phiên bản được chế nhạo. 'HttpRuntime.Cache.Add (cacheKey, sampleUser, null, DateTime.Now.AddHours (2), Cache.NoSlidingExpiration, CacheItemPriority.Normal, null); var context = new Mock (); context.Setup (x => x.Cache) .Returns (HttpRuntime.Cache); ' – Lavamantis

Các vấn đề liên quan