0

私はSteve Sanderson's MVC3 bookのコードサンプルに続いて、ControlContextモックコードがあります。フォームとクエリ文字列の値を設定できます。モックMVC3 ControllerContextクエリ文字列コレクションとValueProvider

ユニットテストでTryUpdateModelをサポートするために、私はコードにいくつかの変更を加えた、例えば私はFormCollection formValuesにformValuesのデータ・タイプを変更したと私はそれを動作させるために、次のコードを追加:

 // form Values values setup 
     this.Request.Setup(x => x.Form).Returns(formValues); 

     // wire up form with value provider 
     if (formValues != null) 
     { 
      onController.ValueProvider = formValues.ToValueProvider(); 
     } 

一方私はクエリーコレクションに同じことをしたいのですが、そのような関数をサポートする同等のクラスは見つかりませんでした。

クエリ文字列にはどうすればよいですか?

+0

ハイテクです - あなたはこれを見つけましたか?ありがとう – andrew

+0

はい、私の自身の答えを下記に見てください。 – hardywang

答えて

1

結局、これが私の解決策

using System; 
using System.Collections.Generic; 
using System.Web; 
using System.Web.Mvc; 
using System.Web.Routing; 
using Moq; 

/// <summary> 
/// A helper class for MVC projects' unit testing. 
/// </summary> 
public class ContextMocks 
{ 
    /// <summary> 
    /// Initializes a new instance of the ContextMocks class. 
    /// </summary> 
    /// <param name="onController">The controller to mock.</param> 
    /// <param name="identityName">The fake security identity name for controller.</param> 
    /// <param name="queryStrings">Fake query string values of the Http context.</param> 
    /// <param name="formValues">Fake form values of the Http context.</param> 
    /// <param name="isNewSession">Enables us to mock if the session was created for the current thread or not.</param> 
    public ContextMocks(Controller onController, string identityName, FormCollection queryStrings, FormCollection formValues, bool isNewSession = true) 
    { 
     this.Cookies = new HttpCookieCollection(); 

     this.Request = new Mock<HttpRequestBase>(); 

     this.Response = new Mock<HttpResponseBase>(); 

     this.Server = new Mock<HttpServerUtilityBase>(); 

     // Define all the common context objects, plus relationships between them 
     this.HttpContext = new Mock<HttpContextBase>(); 
     this.HttpContext.Setup(x => x.Request).Returns(this.Request.Object); 
     this.HttpContext.Setup(x => x.Response).Returns(this.Response.Object); 
     this.HttpContext.Setup(x => x.Session).Returns(new FakeSessionState(isNewSession)); 
     this.HttpContext.Setup(x => x.Application).Returns(new FakeApplicationState()); 
     this.HttpContext.Setup(x => x.User.Identity.Name).Returns(identityName); 
     this.HttpContext.Setup(x => x.Server).Returns(this.Server.Object); 

     // cookie setup 
     this.Request.Setup(x => x.Cookies).Returns(this.Cookies); 
     this.Response.Setup(x => x.Cookies).Returns(this.Cookies); 

     // query string setup 
     this.Request.Setup(x => x.QueryString).Returns(queryStrings); 

     // wire up form with value provider 
     if (queryStrings != null) 
     { 
      onController.ValueProvider = queryStrings.ToValueProvider(); 
     } 

     // form Values values setup 
     this.Request.Setup(x => x.Form).Returns(formValues); 

     // wire up form with value provider 
     if (formValues != null) 
     { 
      onController.ValueProvider = formValues.ToValueProvider(); 
     } 

     // Apply the mock context to the supplied controller instance 
     RequestContext rc = new RequestContext(this.HttpContext.Object, new RouteData()); 
     onController.ControllerContext = new ControllerContext(rc, onController); 
    } 

    /// <summary> 
    /// Initializes a new instance of the ContextMocks class. By using this constructor the mock will also enable UrlHelper mocking 
    /// by using routing table setting. 
    /// </summary> 
    /// <param name="onController">The controller to mock.</param> 
    /// <param name="registerRouteTable"> 
    /// A delegate to the function to register route table. 
    /// Typically it is MvcApplication.RegisterRoutes function in global.asax.cs. 
    /// </param> 
    /// <param name="identityName">The fake security identity name for controller.</param> 
    /// <param name="queryStrings">Fake query string values of the Http context.</param> 
    /// <param name="formValues">Fake form values of the Http context.</param> 
    /// <param name="isNewSession">Enables us to mock if the session was created for the current thread or not.</param> 
    public ContextMocks(
     Controller onController, 
     Action<RouteCollection> registerRouteTable, 
     string identityName, 
     FormCollection queryStrings, 
     FormCollection formValues, 
     bool isNewSession = true) 
     : this(onController, identityName, queryStrings, formValues, isNewSession) 
    { 
     this.Response.Setup(x => x.ApplyAppPathModifier(It.IsAny<string>())).Returns<string>(s => s); 

     // Arrange (get the routing config and test context) 
     RouteCollection routeConfig = new RouteCollection(); 
     registerRouteTable(routeConfig); 
     onController.Url = new UrlHelper(new RequestContext(this.HttpContext.Object, new RouteData()), routeConfig); 
    } 

    /// <summary> 
    /// Gets Http Context mock. 
    /// </summary> 
    public Mock<HttpContextBase> HttpContext { get; private set; } 

    /// <summary> 
    /// Gets Http request mock. 
    /// </summary> 
    public Mock<HttpRequestBase> Request { get; private set; } 

    /// <summary> 
    /// Gets Http response mock. 
    /// </summary> 
    public Mock<HttpResponseBase> Response { get; private set; } 

    /// <summary> 
    /// Gets the mock server object. 
    /// </summary> 
    public Mock<HttpServerUtilityBase> Server { get; private set; } 

    /// <summary> 
    /// Gets Route data. 
    /// </summary> 
    public RouteData RouteData { get; private set; } 

    /// <summary> 
    /// Gets or sets A collection used to hold fake cookie values. 
    /// </summary> 
    private HttpCookieCollection Cookies 
    { 
     get; 
     set; 
    } 

    /// <summary> 
    /// Use queryStringCollectionProvider fake HttpSessionStateBase, because it's hard to mock it with Moq. 
    /// </summary> 
    private class FakeSessionState : HttpSessionStateBase 
    { 
     /// <summary> 
     /// Enables us to mock whether the session was created for the current thread or not. 
     /// </summary> 
     private bool isNewSession; 

     /// <summary> 
     /// Fake session state collection. 
     /// </summary> 
     private Dictionary<string, object> items = new Dictionary<string, object>(); 

     /// <summary> 
     /// Initializes a new instance of the FakeSessionState class. 
     /// </summary> 
     /// <param name="isNewSession">Enables us to mock if the session was created for the current thread or not.</param> 
     public FakeSessionState(bool isNewSession) 
     { 
      this.isNewSession = isNewSession; 
     }   

     /// <summary> 
     /// Gets a value that indicates whether the session was created during the current request. 
     /// </summary> 
     public override bool IsNewSession 
     { 
      get 
      { 
       return this.isNewSession; 
      } 
     } 

     /// <summary> 
     /// An indexer to access the fake session item. 
     /// </summary> 
     /// <param name="name">Name of fake session key.</param> 
     /// <returns>Fake session value.</returns> 
     public override object this[string name] 
     { 
      get { return this.items.ContainsKey(name) ? this.items[name] : null; } 
      set { this.items[name] = value; } 
     } 

     /// <summary> 
     /// Empties the contents of the session. 
     /// </summary> 
     public override void Abandon() 
     { 
      this.items = new Dictionary<string, object>(); 
     } 
    } 

    /// <summary> 
    /// Use queryStringCollectionProvider fake HttpApplicationStateBase, because it's hard to mock it with Moq. 
    /// </summary> 
    private class FakeApplicationState : HttpApplicationStateBase 
    { 
     /// <summary> 
     /// Fake application state collection. 
     /// </summary> 
     private Dictionary<string, object> items = new Dictionary<string, object>(); 

     /// <summary> 
     /// An indexer to access the fake application item. 
     /// </summary> 
     /// <param name="name">Name of fake application key.</param> 
     /// <returns>Fake application value.</returns> 
     public override object this[string name] 
     { 
      get { return this.items.ContainsKey(name) ? this.items[name] : null; } 
      set { this.items[name] = value; } 
     } 

     /// <summary> 
     /// Mock out of the lock method. 
     /// </summary> 
     public override void Lock() 
     { 
     } 

     /// <summary> 
     /// Mock out of the unlock method. 
     /// </summary> 
     public override void UnLock() 
     { 
     } 

     /// <summary> 
     /// Adds the fake object to the application object. 
     /// </summary> 
     /// <param name="name">The key</param> 
     /// <param name="value">The value being added in conjunction with the key.</param> 
     public override void Add(string name, object value) 
     { 
      this.items.Add(name, value); 
     } 
    } 
} 
+0

情報ありがとう – andrew

関連する問題