12

W końcu udało mi się uzyskać HttpContext.Current, aby nie być pustym przez znalezienie kodu online. Ale nadal nie mogę dodać niestandardowych nagłówków do żądania w moim teście jednostki. Oto mój test:Konieczność dodania niestandardowego nagłówka do żądania w teście jednostkowym

[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); 
    } 

To jest testowany kod.

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

Nie lubię odpowiedź przez @yzicus poniżej. Czy ktoś wie, jak dodać nagłówki do fałszywego żądania * bez * zmiany całego kodu źródłowego, aby użyć HttpContextFactory? –

Odpowiedz

3

Możesz użyć tego, że pracował z:

Setting HttpContext.Current.Session in a unit test

użytkownika odpowiedź Antoniego i dodać ten kod w GetMockedHttpContext:

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

następnie można dodać:

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

dzięki temu możesz publikować nagłówki. Ale niestety trzeba użyć HttpContextFactory zamiast HttpContext

0

Dzięki blogu Adama Reeda możliwe jest modyfikowanie kolekcji nagłówków za pomocą refleksji: 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); 
Powiązane problemy