12

Ich konnte schließlich die HttpContext.Current nicht Null sein, indem Sie einige Code online. Aber ich bin noch nicht in der Lage, benutzerdefinierte Header zu der Anfrage in meinem Komponententest hinzuzufügen. Hier ist mein Test:Müssen benutzerdefinierte Header zu Anfrage in Unit-Test

[TestClass] 
public class TagControllerTest 
{ 
    private static Mock<IGenericService<Tag>> Service { get; set; } 
    private TagController controller; 

    [TestInitialize] 
    public void ThingServiceTestSetUp() 
    { 
     Tag tag = new Tag(1, "people"); 
     Response<Tag> response = new Response<Tag>(); 
     response.PayLoad = new List<Tag>() { tag }; 

     Service = new Mock<IGenericService<Tag>>(MockBehavior.Default); 
     Service.Setup(s => s.FindAll("username", "password", "token")).Returns(response); 

     controller = new TagController(Service.Object); 
     HttpContext.Current = FakeHttpContext(); 
    } 

    public static HttpContext FakeHttpContext() 
    { 
     var httpRequest = new HttpRequest("", "http://kindermusik/", ""); 
     var stringWriter = new StringWriter(); 
     var httpResponce = new HttpResponse(stringWriter); 
     var httpContext = new HttpContext(httpRequest, httpResponce); 

     var sessionContainer = new HttpSessionStateContainer("id", new SessionStateItemCollection(), 
               new HttpStaticObjectsCollection(), 10, true, 
               HttpCookieMode.AutoDetect, 
               SessionStateMode.InProc, false); 

     httpContext.Items["AspSession"] = typeof(HttpSessionState).GetConstructor(
            BindingFlags.NonPublic | BindingFlags.Instance, 
            null, CallingConventions.Standard, 
            new[] { typeof(HttpSessionStateContainer) }, 
            null) 
          .Invoke(new object[] { sessionContainer }); 
     httpContext.Request.Headers["username"] = "username"; //It throws a PlatformNotSupportedException exception 
     httpContext.Request.Headers["password"] = "password"; //.Headers.Add("blah", "blah") throws same error 
     httpContext.Request.Headers["token"] = "token"; //And so to .Headers.Set("blah", "blah") 

     return httpContext; 
    } 

    [TestMethod] 
    public void TagControllerGetTest() 
    { 
     // Arrange 
     Response<Tag> result = controller.Get(); 

     // Assert 
     Assert.AreEqual(true, result.IsSuccess); 
     Assert.AreEqual(1, result.PayLoad.Count); 
     Assert.AreEqual("people", result.PayLoad[0].Name); 
    } 

Dies ist der Code, der getestet wird.

public class TagController : ApiController 
{ 
    public IGenericService<Tag> _service; 

    public TagController() 
    { 
     _service = new TagService(); 
    } 

    public TagController(IGenericService<Tag> service) 
    { 
     this._service = service; 
    } 

    // GET api/values 
    public Response<Tag> Get() 
    { 
     HttpContext context = HttpContext.Current; 
     string username = context.Request.Headers["username"].ToString(); 
     string password = context.Request.Headers["password"].ToString(); 
     string token = context.Request.Headers["token"].ToString(); 
     return (Response<Tag>) _service.FindAll(username, password, token); 
    } 
} 
+1

Ich mag die Antwort nicht von @yzicus unten. Weiß jemand, wie man Header zu einer Scheinanfrage hinzufügt * ohne * den gesamten Quellcode zu ändern, um HttpContextFactory zu verwenden? –

Antwort

3

Sie können dies nutzen, es funktionierte mit:

Setting HttpContext.Current.Session in a unit test

Benutzer Anthony Antwort, und fügen Sie diesen Code in GetMockedHttpContext:

request.SetupGet(req => req.Headers).Returns(new NameValueCollection()); 

dann können Sie hinzufügen:

HttpContextFactory.Current.Request.Headers.Add(key, value); 

damit können Sie Header hochladen. Aber leider muss man HttpContextFactory anstelle von Httpcontext

0

Dank Adam Reed Blog es möglich ist, Headers Sammlung ändern Reflexion mit: MOCK HTTPCONTEXT.CURRENT.REQUEST.HEADERS UNIT TEST

HttpContext.Current = new HttpContext(
new HttpRequest("", "http://tempuri.org", ""), new HttpResponse(new StringWriter())); 

NameValueCollection headers = HttpContext.Current.Request.Headers; 

Type t = headers.GetType(); 
const BindingFlags nonPublicInstanceMethod = BindingFlags.InvokeMethod | BindingFlags.NonPublic | BindingFlags.Instance; 

t.InvokeMember("MakeReadWrite", nonPublicInstanceMethod, null, headers, null); 
t.InvokeMember("InvalidateCachedArrays", nonPublicInstanceMethod, null, headers, null); 

// eg. add Basic Authorization header 
t.InvokeMember("BaseRemove", nonPublicInstanceMethod, null, headers, new object[] { "Authorization" }); 
t.InvokeMember("BaseAdd", nonPublicInstanceMethod, null, headers, 
    new object[] { "Authorization", new ArrayList{"Basic " + api_key} }); 

t.InvokeMember("MakeReadOnly", nonPublicInstanceMethod, null, headers, null);