2017-08-25 226 views
1

我有一个自定义的授权属性见下面,我试图编写一个单元测试来测试它的功能。单元测试模拟HttpActionContext

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转换为真实的。下面是我的测试代码

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工作

+0

您调用模拟对象这样'ClassUnderTest.OnAuthorization(context.Object);'你还需要模拟其他授权明智空校验将 – Nkosi

+0

您使用的起订量永远是假的呢?上次我使用moq时,我不得不使用.Object字段,在你的情况下:ClassUnderTest.OnAuthorization(context.Object); – pmezykowski

回答

2

您可以使用实际的对象,并以行使测试方法提供了模拟因为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 
    //... 
} 
+0

谢谢,这是正确地将它传递给方法。但是我挣扎着找到要反对的东西,因为这个方法是无效的并且没有返回 –

+1

Assert.IsNull(context.Response)似乎能够工作,因为如果它到了HandleUnauthorizedRequest方法中它只会被分配一个响应 –