Asp.net-Mvc

你如何模擬 asp.net mvc 中的記憶體對象?

  • January 1, 2017

我將如何模擬 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; 

編輯:我找到了一種更簡單的方法,至少在您使用空記憶體進行測試時。使用 HttpRunTime.Cache 作為您對 HttpContext 的 Cache 屬性的期望的返回值。對於更高級的場景,使用包裝器和模擬可能仍然是更好的處理方式——例如,如果您需要測試記憶體中的異常。

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

原文

包裝類是要走的路,但我認為你在錯誤的地方應用它。我會給我的控制器一個 CacheWrapper 屬性,然後創建一個建構子,允許我傳入一個可以設置該屬性的 CacheWrapper 實例。預設情況下,控制器使用 HttpContext.Current.Cache 創建一個 CacheWrapper。在您的測試程式碼中,構造一個模擬 CacheWrapper 以傳遞給控制器的建構子。這樣,您根本不需要創建模擬 Cache 對象——這很難,因為它是一個密封的類。

或者,您可以只實例化 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();
}

引用自:https://stackoverflow.com/questions/783228