.net - 由于 .net MVC 中的 HttpContext,测试我的 Controller 引发错误

标签 .net asp.net-mvc asp.net-mvc-3 forms-authentication mstest

我有一个调用 HttpContext 的 Controller ,如下所示:

[Authorize(Roles = "Administrador")]
public class ApuradorController : Controller
{
    private readonly Questiona2011Context _context = new Questiona2011Context();

    private readonly AuthenticationService _authenticationService = new AuthenticationService();
}

在 AuthenticationService 类中调用 HttpContext:

public class AuthenticationService
{
    private IPrincipal _user = HttpContext.Current.User;

    ...
}

在我的项目中,当我实例化 Controller 时,我测试 Controller ,private IPrincipal _user = HttpContext.Current.User; 中抛出错误:对象引用未设置到实例一个对象。

测试我的 Controller 需要什么?

最佳答案

您最缺少的就是如何设计用于测试的 ASP.NET MVC 项目的知识。

您应该设计 Controller 以使用依赖项注入(inject)。也就是说, Controller 不应该使用 AuthenticationService 的具体实现,而应该使用 IAuthenticationService,其具体实现将在运行时提供。目前,当创建 Controller 时,也会创建 AuthenticationService。但在测试场景中,HttpContext 为 null,并且创建 AuthenticationService 失败并出现 NullReference 异常。如果您通过接口(interface)进行设计,则出于测试目的,您将向 Controller 提供 AuthenticationService 的虚假实现,并且它不会抛出异常。

public interface IAuthenticationService
{
    IPrincipal User {get;}
}

public class AuthenticationService : IAuthenticationService
{
    private IPrincipal _user = HttpContext.Current.User;

    ...
}

//the controller
[Authorize(Roles = "Administrador")]
public class ApuradorController : Controller
{
    private readonly Questiona2011Context _context = new Questiona2011Context();

    private readonly IAuthenticationService _authenticationService;

    public ApuradorController(IAuthenticationService authenticationService)
    {
         _authenticationService = authenticationService;
    }
}

在测试场景中,您可以使用一些模拟库来伪造 IAuthenticationService 实现,例如 moq 。并通过模拟为其提供值(value)

var mockAuthenticationService = new Mock<IAuthenticationService>();
//setup mockAuthenticationService

var controller = new ApuradorController(mockAuthenticationService.Object);

这次不会抛出异常。

如果您不了解可单元测试项目设计的原则,上述信息就没有帮助。如需快速入门,请阅读this关联。对于进一步阅读有关 ASP.NET MVC 的地址书籍,我会推荐 Steven Sanderson 的那些书籍。可单元测试的 Controller 设计的主要思想是,您应该有能力向 Controller 提供假组件、假存储库、服务等,并仅保留 Controller 中经过单元测试的部分。然后用这些假零件测试 Controller 迭代。单元测试意味着测试交互。如果交互正确,那么这些组件的实际实现也将是正确的。如果他们错了,测试就会失败。

关于.net - 由于 .net MVC 中的 HttpContext,测试我的 Controller 引发错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6897826/

相关文章:

javascript - 使用 Angular 将表单发布到 ASP.NET MVC ActionMethod

c# - 为什么这在我从 Visual Studio 调试时有效,但在我部署到 IIS 后却不起作用?

asp.net-mvc - ASP.NET MVC 如何应用基于角色或基于身份验证的 View 呈现?

asp.net-mvc-3 - EF : Should entities have business logic?

.net - Sleep(10)什么都不做?

.net - 我可以通过编程方式修改 ARR Affinition cookies 的值吗

.net - 有没有类似 TypeMock 的开源 mocking 框架?

asp.net - 无法从 MVC2 升级到 MVC3

c# - INSERT 语句与 FOREIGN KEY 冲突

c# - 使用 "ref"和/或 "out"作为对象类型