用于单元测试的Mock HttpActionContext

时间:2017-08-25 19:18:11

标签: c# unit-testing moq vs-unit-testing-framework

我有一个自定义授权属性,如下所示,我正在尝试编写一个单元测试来测试其功能。

    public override void OnAuthorization(System.Web.Http.Controllers.HttpActionContext actionContext)
    {
        if (actionContext.Request.Headers.Authorization != null)
        {
            // get the Authorization header value from the request and base64 decode it
            string userInfo = Encoding.Default.GetString(Convert.FromBase64String(actionContext.Request.Headers.Authorization.Parameter));

            // custom authentication logic
            if (string.Equals(userInfo, string.Format("{0}:{1}", "user", "pass")))
            {
                IsAuthorized(actionContext);
            }
            else
            {
                HandleUnauthorizedRequest(actionContext);
            }
        }
        else
        {
            HandleUnauthorizedRequest(actionContext);
        }
    }

    protected override void HandleUnauthorizedRequest(System.Web.Http.Controllers.HttpActionContext actionContext)
    {
        actionContext.Response = new HttpResponseMessage(System.Net.HttpStatusCode.Unauthorized)
        {
            ReasonPhrase = "Unauthorized"
        };
    }

我的问题是,当我尝试测试时,我得到" System.NullReferenceException:对象引用未设置为对象的实例。"我试图设置actionContext的request.headers.authorization值,但它没有setter。当我尝试模拟HttpActionContext时,它说它无法从模拟HttpActionContext转换为真实的HttpActionContext。以下是我的测试代码

public class HttpBasicAuthorizeAttributeTest
{
    private HttpBasicAuthorizeAttribute ClassUnderTest { get; set; }

    private HttpActionContext actionContext { get; set; }

    [TestMethod]
    public void HttpBasicAuthorizeAttribute_OnAuthorize_WithAuthorizedUser_ReturnsAuthorization()
    {
       var context = new Mock<HttpActionContext>();
       context.Setup(x => x.Request.Headers.Authorization.Parameter).Returns("bzUwkDal=");
       ClassUnderTest.OnAuthorization(context);
    }

    [TestInitialize]
    public void Initialize()
    {
        ClassUnderTest = new HttpBasicAuthorizeAttribute();
        actionContext = new HttpActionContext();
    }
}

*省略断言,直到我甚至可以让HttpActionContext工作

1 个答案:

答案 0 :(得分:6)

您可以使用实际对象并将其提供给模拟,以便将测试中的方法作为Moq运行,无法模拟非虚拟成员。

[TestMethod]
public void HttpBasicAuthorizeAttribute_OnAuthorize_WithAuthorizedUser_ReturnsAuthorization() {
   //Arrange
    var context = new HttpActionContext();
    var headerValue = new AuthenticationHeaderValue("Basic", "bzUwkDal=");
    var request = new HttpRequestMessage();
    request.Headers.Authorization = headerValue;
    var controllerContext = new HttpControllerContext();
    controllerContext.Request = request;
    context.ControllerContext = controllerContext;

   //Act
   ClassUnderTest.OnAuthorization(context);

   //Assert
   //...
}