12

Infine, è stato possibile ottenere il valore HttpContext.Current non risultando nullo trovando un codice online. Ma non sono ancora riuscito ad aggiungere intestazioni personalizzate alla richiesta nel mio test di unità. Ecco il mio test:È necessario aggiungere un'intestazione personalizzata per richiedere il test dell'unità

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

Questo è il codice che viene testato.

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

non mi piace la risposta @yzicus di seguito. Qualcuno sa come aggiungere intestazioni a una richiesta fittizia * senza * cambiando tutto il codice sorgente per utilizzare HttpContextFactory? –

risposta

3

È possibile utilizzare questo, ha funzionato con:

Setting HttpContext.Current.Session in a unit test

utente la risposta di Anthony, e aggiungere questo codice in GetMockedHttpContext:

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

quindi è possibile aggiungere:

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

da questo è possibile pubblicare le intestazioni. Ma purtroppo si deve utilizzare HttpContextFactory invece di HttpContext

0

Grazie al blog di Adam Reed è possibile modificare la raccolta intestazioni usando riflessione: 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);