如何在单元测试中模拟 Cookie
How Mock Cookie in Unit test
我有一个 MVC 控制器,我正在其中创建 cookie 并执行其余操作。我需要对这个方法进行单元测试。我不确定如何模拟 cookie。
这是我在控制器中的方法:
public ActionResult Login(LogInRequest logInRequest)
{
if (ModelState.IsValid)
{
HttpCookie usercookie = new HttpCookie("usercookie");
usercookie["UserName"] = logInRequest.UserName;
usercookie["Password"] = logInRequest.Password;
usercookie.Expires = DateTime.Now.AddMinutes(10);
**Response.Cookies.Add(usercookie);**
return RedirectToAction("search", "LoanDriver");
.......
return View(logInRequest);
}
这一行 Response.Cookies.Add(usercookie);它给了我一个 Null 错误。当我追踪 cookie 时,它具有价值。
这是我的测试方法:
public void Web_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://dev.loans.carfinance.com/internal";
var server = new HttpServer(new HttpConfiguration(), fakeResponseHandler);
var httpClient = new HttpClient(server);
var controller = new LoanDriverController(httpClient);
Fake.SetFakeContext(controller);
var result = controller.Login(request);
Assert.IsNotNull(result);
}
}
我也尝试过将 cookie 添加到 Response 中,但没有成功并遇到同样的问题:
public static void SetFakeContext(this Controller controller)
{
var httpContext = InitialiseFakeHttpContext();
ControllerContext context =
new ControllerContext(new RequestContext(httpContext, new RouteData()), controller);
controller.ControllerContext = context;
}
private 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;
}
我认为您可以通过在控制器中进行一些重构来处理这个问题,例如,您可以创建一个 ICookieManager 接口和一个 CookieManager class(此 class 包含添加 cookie 的逻辑,也实现了 ICookieManager 接口)然后你可以将这个 ICookieManager 添加为构造函数中的依赖项或作为 属性 然后你将能够在你的单元测试中模拟这个依赖项,就像这样:
public interface ICookieManager
{
void CreateUserCookie(string userName, string password, HttpResponseBase response, int expiration = 10);
}
public class CookieManager: ICookieManager
{
public void CreateUserCookie(string userName, string password, HttpResponseBase response, int expiration = 10)
{
HttpCookie usercookie = new HttpCookie("usercookie");
usercookie["UserName"] = userName;
usercookie["Password"] = password;
usercookie.Expires = DateTime.Now.AddMinutes(expiration);
response.Cookies.Add(usercookie);
}
}
在你的控制器中:
public class YourController : Controller
{
public ICookieManager CookieManager { get; set; }
public YourController()
{
CookieManager = new CookieManager();
}
public YourController(ICookieManager cookieManager)
{
CookieManager = cookieManager;
}
public ActionResult Login(LogInRequest logInRequest)
{
if (ModelState.IsValid)
{
CookieManager.CreateUserCookie(logInRequest.UserName, logInRequest.Password, Response);
return RedirectToAction("search", "LoanDriver");
}
}
}
在你的单元测试中:
public void Web_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://dev.loans.carfinance.com/internal";
var server = new HttpServer(new HttpConfiguration(), fakeResponseHandler);
var httpClient = new HttpClient(server);
var controller = new LoanDriverController(httpClient);
controller.CookieManager=mockOfYourCookieManager; //here you pass the instance of the mock or also you can passe it in the constructor of the controller.
Fake.SetFakeContext(controller);
var result = controller.Login(request);
Assert.IsNotNull(result);
}
我有一个 MVC 控制器,我正在其中创建 cookie 并执行其余操作。我需要对这个方法进行单元测试。我不确定如何模拟 cookie。
这是我在控制器中的方法:
public ActionResult Login(LogInRequest logInRequest)
{
if (ModelState.IsValid)
{
HttpCookie usercookie = new HttpCookie("usercookie");
usercookie["UserName"] = logInRequest.UserName;
usercookie["Password"] = logInRequest.Password;
usercookie.Expires = DateTime.Now.AddMinutes(10);
**Response.Cookies.Add(usercookie);**
return RedirectToAction("search", "LoanDriver");
.......
return View(logInRequest);
}
这一行 Response.Cookies.Add(usercookie);它给了我一个 Null 错误。当我追踪 cookie 时,它具有价值。
这是我的测试方法:
public void Web_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://dev.loans.carfinance.com/internal";
var server = new HttpServer(new HttpConfiguration(), fakeResponseHandler);
var httpClient = new HttpClient(server);
var controller = new LoanDriverController(httpClient);
Fake.SetFakeContext(controller);
var result = controller.Login(request);
Assert.IsNotNull(result);
}
}
我也尝试过将 cookie 添加到 Response 中,但没有成功并遇到同样的问题:
public static void SetFakeContext(this Controller controller)
{
var httpContext = InitialiseFakeHttpContext();
ControllerContext context =
new ControllerContext(new RequestContext(httpContext, new RouteData()), controller);
controller.ControllerContext = context;
}
private 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;
}
我认为您可以通过在控制器中进行一些重构来处理这个问题,例如,您可以创建一个 ICookieManager 接口和一个 CookieManager class(此 class 包含添加 cookie 的逻辑,也实现了 ICookieManager 接口)然后你可以将这个 ICookieManager 添加为构造函数中的依赖项或作为 属性 然后你将能够在你的单元测试中模拟这个依赖项,就像这样:
public interface ICookieManager
{
void CreateUserCookie(string userName, string password, HttpResponseBase response, int expiration = 10);
}
public class CookieManager: ICookieManager
{
public void CreateUserCookie(string userName, string password, HttpResponseBase response, int expiration = 10)
{
HttpCookie usercookie = new HttpCookie("usercookie");
usercookie["UserName"] = userName;
usercookie["Password"] = password;
usercookie.Expires = DateTime.Now.AddMinutes(expiration);
response.Cookies.Add(usercookie);
}
}
在你的控制器中:
public class YourController : Controller
{
public ICookieManager CookieManager { get; set; }
public YourController()
{
CookieManager = new CookieManager();
}
public YourController(ICookieManager cookieManager)
{
CookieManager = cookieManager;
}
public ActionResult Login(LogInRequest logInRequest)
{
if (ModelState.IsValid)
{
CookieManager.CreateUserCookie(logInRequest.UserName, logInRequest.Password, Response);
return RedirectToAction("search", "LoanDriver");
}
}
}
在你的单元测试中:
public void Web_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://dev.loans.carfinance.com/internal";
var server = new HttpServer(new HttpConfiguration(), fakeResponseHandler);
var httpClient = new HttpClient(server);
var controller = new LoanDriverController(httpClient);
controller.CookieManager=mockOfYourCookieManager; //here you pass the instance of the mock or also you can passe it in the constructor of the controller.
Fake.SetFakeContext(controller);
var result = controller.Login(request);
Assert.IsNotNull(result);
}