使用 NSubstitute 在 MVC 单元测试中模拟用户 IP 地址
Mocking user IP address in MVC unit test with NSubstitute
我的 HomeController 中有以下方法。目的是根据IP地址拆分用户,测试不同版本的首页:
[HttpGet]
public ActionResult Index()
{
var userIpAddress = GetUserIpAddress();
if (IsIpAddressOddOrEven(userIpAddress))
{
return RedirectToAction(HomePage);
}
return RedirectToAction(HomePageAlternative);
}
GetUserIpAddress
方法:
private string GetUserIpAddress()
{
HttpContext context = System.Web.HttpContext.Current;
var ipAddress = context.Request.ServerVariables["HTTP_X_FORWARDED_FOR"];
if (!string.IsNullOrEmpty(ipAddress))
{
string[] addresses = ipAddress.Split(',');
if (addresses.Length != 0)
{
return addresses[0];
}
}
return context.Request.ServerVariables["REMOTE_ADDR"];
}
我想编写一个单元测试以确保其正常工作。但是,每次运行单元测试时,它只是获取我当前拥有的 IP 地址。我正在努力研究如何将 'GetUserIpAddress' 方法的结果模拟为 return 奇数或偶数字符串。我目前的尝试:
[Test]
public void Test()
{
var controller = CreateMvcController<HomeController>();
var result = controller.Index();
controller.HttpContext.Request.ServerVariables["HTTP_X_FORWARDED_FOR"].Returns("1");
Assert.IsInstanceOf<RedirectToRouteResult>(result);
var redirectToRouteResult = result as RedirectToRouteResult;
Assert.AreEqual(HomeController.HomePage, redirectToRouteResult.RouteValues["action"]);
}
我得到的错误是 controller.HttpContext.Request.ServerVariables["HTTP_X_FORWARDED_FOR"].Returns("1");
的结果不是一个字符串而是一个 HttpResponseBase,无论如何我不相信我正在以正确的方式处理这个问题。请有人能指出我正确的方向吗?谢谢
我建议您将 GetUserIpAddress
方法移动到可以注入 HomeController
的助手 class。因此,您可以在进行单元测试时模拟它。
你的HomeController
会是这样
public HomeController(IUserIpAddressHelper userIpAddressHelper)
{
_userIpAddressHelper = userIpAddressHelper;
}
[HttpGet]
public ActionResult Index()
{
var userIpAddress = _userIpAddressHelper.GetUserIpAddress(System.Web.HttpContext.Current);
if (_userIpAddressHelper.IsIpAddressOddOrEven(userIpAddress))
{
return RedirectToAction(HomePage);
}
return RedirectToAction(HomePageAlternative);
}
因此,您将能够模拟 UserIpAddressHelper
并在编写测试时注入它。
public void Test()
{
var userIpAddressHelper = Substitute.For<IUserIpAddressHelper>();
userIpAddressHelper.GetUserIpAddress(Arg.Any<HttpContext>()).Returns("0.0.0.0");
var controller = new HomeController(userIpAddressHelper);
var result = controller.Index();
Assert.IsInstanceOf<RedirectToRouteResult>(result);
var redirectToRouteResult = result as RedirectToRouteResult;
Assert.AreEqual(HomeController.HomePage, redirectToRouteResult.RouteValues["action"]);
}
我的 HomeController 中有以下方法。目的是根据IP地址拆分用户,测试不同版本的首页:
[HttpGet]
public ActionResult Index()
{
var userIpAddress = GetUserIpAddress();
if (IsIpAddressOddOrEven(userIpAddress))
{
return RedirectToAction(HomePage);
}
return RedirectToAction(HomePageAlternative);
}
GetUserIpAddress
方法:
private string GetUserIpAddress()
{
HttpContext context = System.Web.HttpContext.Current;
var ipAddress = context.Request.ServerVariables["HTTP_X_FORWARDED_FOR"];
if (!string.IsNullOrEmpty(ipAddress))
{
string[] addresses = ipAddress.Split(',');
if (addresses.Length != 0)
{
return addresses[0];
}
}
return context.Request.ServerVariables["REMOTE_ADDR"];
}
我想编写一个单元测试以确保其正常工作。但是,每次运行单元测试时,它只是获取我当前拥有的 IP 地址。我正在努力研究如何将 'GetUserIpAddress' 方法的结果模拟为 return 奇数或偶数字符串。我目前的尝试:
[Test]
public void Test()
{
var controller = CreateMvcController<HomeController>();
var result = controller.Index();
controller.HttpContext.Request.ServerVariables["HTTP_X_FORWARDED_FOR"].Returns("1");
Assert.IsInstanceOf<RedirectToRouteResult>(result);
var redirectToRouteResult = result as RedirectToRouteResult;
Assert.AreEqual(HomeController.HomePage, redirectToRouteResult.RouteValues["action"]);
}
我得到的错误是 controller.HttpContext.Request.ServerVariables["HTTP_X_FORWARDED_FOR"].Returns("1");
的结果不是一个字符串而是一个 HttpResponseBase,无论如何我不相信我正在以正确的方式处理这个问题。请有人能指出我正确的方向吗?谢谢
我建议您将 GetUserIpAddress
方法移动到可以注入 HomeController
的助手 class。因此,您可以在进行单元测试时模拟它。
你的HomeController
会是这样
public HomeController(IUserIpAddressHelper userIpAddressHelper)
{
_userIpAddressHelper = userIpAddressHelper;
}
[HttpGet]
public ActionResult Index()
{
var userIpAddress = _userIpAddressHelper.GetUserIpAddress(System.Web.HttpContext.Current);
if (_userIpAddressHelper.IsIpAddressOddOrEven(userIpAddress))
{
return RedirectToAction(HomePage);
}
return RedirectToAction(HomePageAlternative);
}
因此,您将能够模拟 UserIpAddressHelper
并在编写测试时注入它。
public void Test()
{
var userIpAddressHelper = Substitute.For<IUserIpAddressHelper>();
userIpAddressHelper.GetUserIpAddress(Arg.Any<HttpContext>()).Returns("0.0.0.0");
var controller = new HomeController(userIpAddressHelper);
var result = controller.Index();
Assert.IsInstanceOf<RedirectToRouteResult>(result);
var redirectToRouteResult = result as RedirectToRouteResult;
Assert.AreEqual(HomeController.HomePage, redirectToRouteResult.RouteValues["action"]);
}