2016-10-04 54 views
0

我有一个OAuthServerProvider认证用户名和密码后发出令牌。当用户名或密码无效时,我拒绝owin上下文,默认情况下将返回400 Bad Request作为状态码。NUnit测试用例跳过owin中间件

但我想用401 Unauthorized

回应要做到这一点我写了一个中间件将检查头,看看自定义标题是存在,如果是将401

替换状态码
if (context.Response.StatusCode == 400 && context.Response.Headers.ContainsKey(Constants.OwinChallengeFlag)) 
{ 
    var headerValues = context.Response.Headers.GetValues(Constants.OwinChallengeFlag); 
    context.Response.StatusCode = Convert.ToInt16(headerValues.FirstOrDefault()); 
    context.Response.Headers.Remove(Constants.OwinChallengeFlag); 
} 

这个工作绝对没问题,当我用小提琴打它时,但是我在下面写的单元测试总是得到400.不知何故,当我用我的单元测试请求中间件时,跳过了。

[TestFixture] 
public class UnitTest1 
{ 
    private TestServer _server; 

    [SetUp] 
    public void SetUp() 
    { 
     _server = TestServer.Create<Startup>(); 
    } 

    [Test] 
    public void ShouldReturnUnauthorizedResponse() 
    { 

     HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, "/token"); 

     //wrong password 
     var requestContent = "grant_type=password&UserName=foo&Password=bar"; 

     request.Content = new StringContent(requestContent, Encoding.UTF8, "application/x-www-form-urlencoded"); 

     var response = _server.HttpClient.SendAsync(request).Result; 

     //This assert fails, but shouldn't 
     Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.Unauthorized)); 
    } 
} 

需要知道我在做什么错在这里。

+0

1)这是一个集成测试而不是单元测试。 2)显示启动配置和完整的中间件。 3)你是否缓冲响应以便下载访问它? – Nkosi

回答

0

我终于想通了....

await _next.Invoke(environment)是罪魁祸首。我用与传入中间件的相同环境字典对象调用它,因此对单元测试没有反映对对象context的修改。

下面的代码按预期方式工作....

public async Task Invoke(IDictionary<string, object> environment) 
{ 
    var context = new OwinContext(environment); 

    var response = context.Response; 

    response.OnSendingHeaders(state => 
    { 
     var resp = (OwinResponse)state; 
     if (resp.StatusCode == 400 && resp.Headers.ContainsKey(Constants.OwinChallengeFlag)) 
     { 
      var headerValues = context.Response.Headers.GetValues(Constants.OwinChallengeFlag); 
      resp.StatusCode = Convert.ToInt16(headerValues.FirstOrDefault()); 
      resp.ReasonPhrase = HttpStatusCode.Unauthorized.ToString(); 
      resp.Headers.Remove(Constants.OwinChallengeFlag); 
     } 
    }, response); 

    await _next.Invoke(context.Environment); 
} 

除了使从改性context对象获得的environment变量,修改响应标头内的response.OnSendingHeaders是必不可少的,这保证了报头之前被修改响应标题被分派。

但是我仍然不知道小提琴手是如何挑选正确的响应状态码的。

希望它可以帮助别人。