我使用NUnit和Moq框架为我的控制器类编写了一个测试类。我的类正在跟随
public class ClientTypeControllerTest
{
private Mock<IClientTypeService> _clientTypeServiceMock;
private Mock<IClientTypeAudService> _clientTypeAudServiceMock;
private Mock<IClientTypeHisService> _clientTypeHisServiceMock;
private Mock<HttpSessionStateBase> _sessionMock;
private Mock<HttpResponseBase> _httpresponceMock;
private Mock<IUserAccountService> _userAccountService;
ClientTypeController objClientTypeController;
protected Users LoggedInUser { get; set; }
List<ClientTypeAud> lists;
[SetUp]
public void Initialize()
{
//System.Diagnostics.Debugger.Launch();
_clientTypeServiceMock = new Mock<IClientTypeService>();
_clientTypeAudServiceMock = new Mock<IClientTypeAudService>();
_clientTypeHisServiceMock = new Mock<IClientTypeHisService>();
_userAccountService = new Mock<IUserAccountService>();
_sessionMock = new Mock<HttpSessionStateBase>();
_httpresponceMock = new Mock<HttpResponseBase>();
var ctrlContext = new Mock<ControllerContext>();
AutoMapperConfiguration.Configure();
_sessionMock.SetupGet(s => s["LOGGED_IN_USER"]).Returns(users);
ctrlContext.Setup(p => p.HttpContext.Session).Returns(_sessionMock.Object);
}
[Test]
public void Show_AllClientTypeRecords_InGridView_UnitTest()
{
lists = new List<ClientTypeAud>() {
new ClientTypeAud() { Id = 1, CTypeName = "INR", CompanyId = 1, Active = "Y" },
new ClientTypeAud() { Id = 1, CTypeName = "ABC", CompanyId = 1, Active = "Y" },
new ClientTypeAud() { Id = 1, CTypeName = "AVM", CompanyId = 1, Active = "Y" }
};
_clientTypeAudServiceMock.Setup(x => x.All()).Returns(lists.AsQueryable());
objClientTypeController = new ClientTypeController(_clientTypeServiceMock.Object,
_clientTypeAudServiceMock.Object, _clientTypeHisServiceMock.Object,
_userAccountService.Object);
var result = objClientTypeController.GridData("", "asc", 1, 1) as JsonResult;
Assert.IsNotNull(result.Data);
}
}
我的BaseController类是,
public class BaseController : Controller
{
public SessionProvider SessionProvider;
protected Users LoggedInUser { get; set; }
public string actionName { get; set; }
protected string controllerName { get; set; }
protected string area { get; set; }
public BaseController()
{
actionName =
System.Web.HttpContext.Current.Request.RequestContext.RouteData.GetRequiredString("action");
controllerName =
System.Web.HttpContext.Current.Request.RequestContext.RouteData.
GetRequiredString("controller");
SessionProvider = new SessionProvider(Session);
LoginMethod();
ViewBag.Menu = BuildMenu();
}
......
......
当我使用NUnit运行我的测试类时,它显示Nullreferenceexception未被用户代码处理
actionName = System.Web.HttpContext.Current.Request.RequestContext.
RouteData.GetRequiredString("action");
这是在我的BaseControllerClass中。所以我不知道如何为HqpContext.Current.Request.RequestContext.so提供数据。请有人请帮助找到解决方案
答案 0 :(得分:1)
你应该为HttpContext操作创建一个包装器,并使用像Rhino Mocks这样的框架模拟UT中的包装调用(通过使用接口)。
您将使用一种方法创建一个接口IHttpContextWrapper&#34; string GetRequiredStringFromRequestRouteData(string valueName)&#34;。
之后,您应该创建接口的实现。说&#34;公共类HttpContextWrapper:IHttpContextWrapper&#34;并且你将在GetRequiredStringFromRequestRouteData的实现中使用HttpContext.Current.Request.RequestContext.RouteData.GetRequiredData(valueName)。
在您的客户端类中,您可以使用依赖注入(通过使用Spring.NET框架或Unity)注入要由属性或构造函数使用的实现。
但是,当你在单元测试中测试客户端时,你将注入一个基于接口创建的模拟对象,你将模拟调用&#34; GetRequiredStringFromRequestRouteData&#34;回报你想要的任何东西。你可以使用像Rhino Mocks这样的Mocking框架来做到这一点。
答案 1 :(得分:1)
您应该为System.Web.dll添加Fakes Assembly
在解决方案资源管理器中,展开单元测试项目的参考文献。
然后创建一个shimcontext并在该上下文中模拟/绕开所需方法的执行。
[TestMethod]
public void TestCurrentYear()
{
using(ShimContext.Create())
{
// Arrange:
System.Web.Fakes.ShimHttpContext....
}
}
来源:http://msdn.microsoft.com/en-us/library/hh549176.aspx,
OR
您可以使用AspNet Simulator尝试不同的方法,该模拟器专门用于在Mvc应用程序的控制器级别进行单元测试。可以在这里找到一个例子: https://github.com/ibrahimbensalah/Xania.AspNet.Simulator/tree/master/Xania.AspNet.Simulator.Tests
答案 2 :(得分:1)
在设置RouteData之前,您需要伪造您的HttpContext。最简单的方法是
HttpContext.Current = new HttpContext(
new HttpRequest("", "http://localhost/", ""),
new HttpResponse(new StringWriter()));
现在您可以编写RequestContext以满足您的要求。首先模拟HttpContext,然后创建RouteData实例。
var contextBase = new Mock<HttpContextBase>();
var routeData = new RouteData();
routeData.Values["controller"] = "anyControllerNameYouWant";
routeData.Values["action"] = "anyActionNameYouWant";
最后一个,只需将这些分配给你的假HttpContext.Current并完成。
HttpContext.Current.Request.RequestContext = new
RequestContext(contextBase.Object, routeData);