如何添加测试cookie以进行请求,以便我可以从Unit测试中测试我的代码。考虑这样的代码:
public ActionResult Dashboard()
{
if (Request.Cookies["usercookie"] == null)
{
return RedirectToAction("Index");
}
return View();
}
我模拟了所有内容,但我不知道如何向cookie中添加内容,因此此行Request.Cookies["usercookie"]
不会返回null。现在它为null并返回给我这个错误:
{“对象引用未设置为对象的实例。”}
这是我的单元测试方法之一:
[TestMethod]
[TestCategory("Unit")]
public void Login_ShouldValidateUserAndLoginSuccessfully()
{
using (var kernel = new NSubstituteMockingKernel())
{
// Setup the dependency incjection
kernel.Load(new EntityFrameworkTestingNSubstituteModule());
// Create test request data
var request = new LogInRequest { UserName = "test", Password = "test" };
var fakeResponseHandler = new FakeResponseHandler();
fakeResponseHandler.AddFakeResponse(new Uri("http://localhost/test"), new HttpResponseMessage(HttpStatusCode.OK));
ConfigurationManager.AppSettings["SearchApiBaseUrl"] = "http://test/internal";
var server = new HttpServer(new HttpConfiguration(), fakeResponseHandler);
var httpClient = new HttpClient(server);
var fakeCookieManager = new FakeCookieManager();
var authenticationService = Substitute.For<IAuthenticationService>();
var newUser = Fake.GetNewUser(1);
var newUserClaim = Fake.GetNewUserClaim(1, newUser.Id, "http://test/identity/claims/loans");
authenticationService.GetUserByEmailPasswordAsync(request.UserName, request.Password).Returns(newUser);
authenticationService.GetUserClaimByEmailAndPasswordAsync(request.UserName, request.Password).Returns(newUserClaim);
var controller = new HomeController(httpClient, fakeCookieManager, null, authenticationService);
Fake.SetFakeAuthenticatedControllerContext(controller);
controller.HttpContext.Session["ReturnUrl"] = "/search";
var result = controller.Login(request);
Assert.IsNotNull(result);
}
}
这是假的Httpcontext中的一个类:
public static HttpContextBase InitialiseFakeHttpContext(string url = "")
{
var HttpContextSub = Substitute.For<HttpContextBase>();
var RequestSub = Substitute.For<HttpRequestBase>();
var ResponseSub = Substitute.For<HttpResponseBase>();
var serverUtilitySub = Substitute.For<HttpServerUtilityBase>();
var itemsSub = Substitute.For<IDictionary>();
HttpContextSub.Request.Returns(RequestSub);
HttpContextSub.Response.Returns(ResponseSub);
HttpContextSub.Server.Returns(serverUtilitySub);
var cookie = Substitute.For<HttpResponseBase>();
HttpContextSub.Response.Returns(cookie);
return HttpContextSub;
}
答案 0 :(得分:4)
这是一个示例单元测试,其中在请求上设置了cookie。
使用NSubstitute框架模拟http上下文,然后设置请求cookie属性。将模拟的http上下文应用于控制器上下文以模拟请求。
[TestClass]
public class MyControllerTests {
[TestMethod]
public void Request_Cookies_Should_Not_Be_Null() {
//Arrange
var cookies = new HttpCookieCollection();
cookies.Add(new HttpCookie("usercookie"));
var mockHttpContext = Substitute.For<HttpContextBase>();
mockHttpContext.Request.Cookies.Returns(cookies);
var sut = new MyController();
sut.ControllerContext = new ControllerContext {
Controller = sut,
HttpContext = mockHttpContext
};
//Act
var result = sut.Dashboard() as ViewResult;
//Assert
Assert.IsNotNull(result);
}
public class MyController : Controller {
public ActionResult Dashboard() {
if (Request.Cookies["usercookie"] == null) {
return RedirectToAction("Index");
}
return View();
}
}
}
<强>更新强>
以下是使用手动创建的模拟HttpContext的测试的更新版本。
[TestClass]
public class MyControllerTests {
[TestMethod]
public void Request_Cookies_Should_Not_Be_Null() {
//Arrange
var cookies = new HttpCookieCollection();
cookies.Add(new HttpCookie("usercookie"));
var mockHttpContext = new MockHttpContext(cookies);
var sut = new MyController();
sut.ControllerContext = new ControllerContext {
Controller = sut,
HttpContext = mockHttpContext
};
//Act
var result = sut.Dashboard() as ViewResult;
//Assert
Assert.IsNotNull(result);
}
public class MyController : Controller {
public ActionResult Dashboard() {
if (Request.Cookies["usercookie"] == null) {
return RedirectToAction("Index");
}
return View();
}
}
private class MockHttpContext : HttpContextBase {
private readonly MockRequest request;
public MockHttpContext(HttpCookieCollection cookies) {
this.request = new MockRequest(cookies);
}
public override HttpRequestBase Request {
get {
return request;
}
}
public class MockRequest : HttpRequestBase {
private readonly HttpCookieCollection cookies;
public MockRequest(HttpCookieCollection cookies) {
this.cookies = cookies;
}
public override HttpCookieCollection Cookies {
get {
return cookies;
}
}
}
}
}
答案 1 :(得分:0)
使用MOQ框架也是一样
MockContext类用于模拟HTTP上下文
public class MockContext
{
public Mock<RequestContext> RoutingRequestContext { get; private set; }
public Mock<HttpContextBase> Http { get; private set; }
public Mock<HttpServerUtilityBase> Server { get; private set; }
public Mock<HttpResponseBase> Response { get; private set; }
public Mock<HttpRequestBase> Request { get; private set; }
public Mock<HttpSessionStateBase> Session { get; private set; }
public Mock<ActionExecutingContext> ActionExecuting { get; private set; }
public HttpCookieCollection Cookies { get; private set; }
public MockContext()
{
this.RoutingRequestContext = new Mock<RequestContext>(MockBehavior.Loose);
this.ActionExecuting = new Mock<ActionExecutingContext>(MockBehavior.Loose);
this.Http = new Mock<HttpContextBase>(MockBehavior.Loose);
this.Server = new Mock<HttpServerUtilityBase>(MockBehavior.Loose);
this.Response = new Mock<HttpResponseBase>(MockBehavior.Loose);
this.Request = new Mock<HttpRequestBase>(MockBehavior.Loose);
this.Session = new Mock<HttpSessionStateBase>(MockBehavior.Loose);
this.Cookies = new HttpCookieCollection();
this.RoutingRequestContext.SetupGet (c => c.HttpContext).Returns(this.Http.Object);
this.ActionExecuting.SetupGet (c => c.HttpContext).Returns(this.Http.Object);
this.Http.SetupGet (c => c.Request).Returns(this.Request.Object);
this.Http.SetupGet (c => c.Response).Returns(this.Response.Object);
this.Http.SetupGet (c => c.Server).Returns(this.Server.Object);
this.Http.SetupGet (c => c.Session).Returns(this.Session.Object);
this.Request.Setup (c => c.Cookies).Returns(Cookies);
}
}
这是测试用例
public void IndexTest()
{
// arrange
MockContext mockContext = new MockContext();
#region creating cookie
HttpCookie cookie = new HttpCookie(Constant.COOKIE_ADMIN_USER_INFO,
Config.DefaultCountryID.ToString());
cookie.Values.Add(Constant.COOKIE_ADMIN_VALUE_COUNTRY_ID,
Config.DefaultCountryID.ToString());
cookie.Values.Add(Constant.COOKIE_ADMIN_VALUE_LANGUAGE_ID,
Config.DefaultLanguageID.ToString());
mockContext.Cookies.Add(cookie);
#endregion
#region Creating controller
ControllerContext controllerContex = new ControllerContext()
{
HttpContext = mockContext.Http.Object
};
HomeController controller = new HomeController()
{
ControllerContext = controllerContex
};
#endregion
// act
var output = (ViewResult)controller.Index();
var result = output.ViewData;
// assert
result.ShouldNotBeNull();
}