Gil*_*ell 11 asp.net nunit rhino-mocks
我看到很多关于HttpSessionState和asp.net MVC的讨论.我正在尝试为asp.net应用程序编写测试,并想知道是否有可能模拟HttpSessionState,如果是这样,怎么样?
我目前正在使用Rhino Mocks和Nunit
小智 11
吉尔伯特
也许我来不及你.我正在使用MSpec,但我认为概念是相似的.我需要在被测控制器中模拟HttpContext的几个组件.
我开始使用以下这些类来模拟HttpContextBase中必要的(为了我的目的)组件.我只覆盖了课程中必要的部分.您对控制器中所需的模拟的需求会有所不同.一旦理解了模式,就可以根据需要添加模拟.
public class MockHttpContext : HttpContextBase
{
private readonly HttpRequestBase _request = new MockHttpRequest();
private readonly HttpServerUtilityBase _server = new MockHttpServerUtilityBase();
private HttpSessionStateBase _session = new MockHttpSession();
public override HttpRequestBase Request
{
get { return _request; }
}
public override HttpServerUtilityBase Server
{
get { return _server; }
}
public override HttpSessionStateBase Session
{
get { return _session; }
}
}
public class MockHttpRequest : HttpRequestBase
{
private Uri _url = new Uri("http://www.mockrequest.moc/Controller/Action");
public override Uri Url
{
get { return _url; }
}
}
public class MockHttpServerUtilityBase : HttpServerUtilityBase
{
public override string UrlEncode(string s)
{
//return base.UrlEncode(s);
return s; // Not doing anything (this is just a Mock)
}
}
public class MockHttpSession : HttpSessionStateBase
{
// Started with sample http://stackoverflow.com/questions/524457/how-do-you-mock-the-session-object-collection-using-moq
// from http://stackoverflow.com/users/81730/ronnblack
System.Collections.Generic.Dictionary<string, object> _sessionStorage = new System.Collections.Generic.Dictionary<string,object>();
public override object this[string name]
{
get { return _sessionStorage[name]; }
set { _sessionStorage[name] = value; }
}
public override void Add(string name, object value)
{
_sessionStorage[name] = value;
}
}
Run Code Online (Sandbox Code Playgroud)
以下是我如何设置Controller Context以使用模拟(MSpec).这是为控制器上的实际测试设置的(测试来自这个类)
public abstract class BlahBlahControllerContext
{
protected static BlahBlahController controller;
Establish context = () =>
{
controller = new BlahBlahController();
controller.ControllerContext = new ControllerContext()
{
Controller = controller,
RequestContext = new RequestContext(new MockHttpContext(), new RouteData()),
};
};
}
Run Code Online (Sandbox Code Playgroud)
为了进一步说明,这是一个使用模拟会话的测试(MSpec世界中的规范):
[Subject("ACCOUNT: Retrieve Password")]
public class retrieve_password_displays_retrieve_password2_page_on_success : BlahBlahControllerContext
{
static ActionResult result;
static RetrievePasswordModel model;
Establish context = () =>
{
model = new RetrievePasswordModel()
{
UserName = "Mike"
};
};
Because of = () =>
{
result = controller.RetrievePassword(model);
};
It should_return_a_RedirectToRouteResult = () =>
{
result.is_a_redirect_to_route_and().action_name().ShouldEqual("RetrievePassword2");
};
It session_should_contain_UN_value = () =>
{
controller.HttpContext.Session["UN"].ShouldEqual("Mike");
};
It session_should_contain_PQ_value = () =>
{
controller.HttpContext.Session["PQ"].ShouldEqual("Question");
};
}
Run Code Online (Sandbox Code Playgroud)
我意识到这不使用Rhino Mocks.我希望它能说明这些原则,读者可以将它用于他们的具体工具和方法.
小智 9
如果您需要为遗留代码测试确切地实例化HttpSessionState,则可以利用FormatterServices机制来获取未初始化的对象.为了使它工作,需要设置private _container字段,就像在内部构造函数中一样
例:
var state = (HttpSessionState) System.Runtime.Serialization
.FormatterServices.GetUninitializedObject(typeof(HttpSessionState));
var containerFld = typeof(HttpSessionState).GetField(
"_container", BindingFlags.Instance | BindingFlags.NonPublic);
var itemCollection = new SessionStateItemCollection();
itemCollection["element"] = 1;
containerFld.SetValue(
state,
new HttpSessionStateContainer(
"1",
itemCollection,
new HttpStaticObjectsCollection(),
900,
true,
HttpCookieMode.UseCookies,
SessionStateMode.InProc,
false
)
);
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
7774 次 |
最近记录: |