2010-08-24 15 views
2

Ce message concerne deux autres messages, here et here.Problème de configuration de simulation d'unité (NUnit) avec HttpHandler

Je suis nouveau à Unit Testing & Mocking. J'ai un appareil de test qui essaie de se moquer d'un objet HttpContext incluant la réponse et la requête. Je pense que le code de test n'est pas configuré correctement, car après avoir appelé le gestionnaire, je reçois une erreur immédiatement. L'erreur que j'obtiens est:

UnitTests.UADHandlerFixture.Request_Is_Object: System.NullReferenceException: Référence d'objet non définie sur une instance d'un objet.

à Abstract.BaseHttpHandler.get_Request() dans BaseHttpHandler.cs: ligne 21

à Abstract.BaseHttpHandler.get_IsRequestFromUAD() dans BaseHttpHandler.cs: ligne 23

à Handlers.UADTimeHttpHandler.ProcessRequest (HttpContextBase contexte) dans UADTimeHttpHandler.cs: ligne 19

à UnitTests.UADHandlerFixture.Request_Is_Object() dans UADHttpHanderTests.cs: ligne 47

Le code de test est la suivante:

[TestFixture] 
public class UADHandlerFixture 
{ 
    private Mock<HttpContextBase> _mockHttpContext; 
    private Mock<HttpRequestBase> _mockHttpRequest; 
    private Mock<HttpResponseBase> _mockHttpResponse; 
    private UADTimeHttpHandler _handler; 
    private WindsorContainer _container; 

    [SetUp] 
    public void Init() 
    { 
     _mockHttpRequest = new Mock<HttpRequestBase>(); 
     _mockHttpResponse = new Mock<HttpResponseBase>(); 
     _mockHttpContext = new Mock<HttpContextBase>(); 
     _container = new WindsorContainer(); 
     _container.AddComponent<ILogger, FakeLogger>(); 
     _container.AddComponent<IDataRepository, FakeDataRepository>(); 

     _mockHttpContext.SetupGet(x => x.Application[0]).Returns(_container); 
     _mockHttpContext.SetupGet(x => x.Request).Returns(_mockHttpRequest.Object); 
     _mockHttpContext.SetupGet(x => x.Response).Returns(_mockHttpResponse.Object); 

     _handler = new UADTimeHttpHandler(); 
    } 

    [Test] 
    public void Request_Is_Object() 
    { 
     _handler.ProcessRequest(_mockHttpContext.Object); 
    } 
} 

Handler:

public class UADTimeHttpHandler : BaseHttpHandler 
{ 
    public override void ProcessRequest(HttpContextBase context) 
    { 
     if (IsRequestFromUAD) 
     { 
      Logger.Log("Log stuff"); 
      DataRepository.Write("DB stuff"); 
      ReturnResponse(HttpStatusCode.OK, DateTime.Now.ToString()); 
     } 
     else 
      ReturnResponse(HttpStatusCode.BadRequest); 
    } 
} 

BaseHandler:

public abstract class BaseHttpHandler : IHttpHandler 
{ 
    private HttpContext _httpContext; 
    private ILogger _logger; 
    private IDataRepository _dataRepository; 
    protected ILogger Logger { get { return _logger; } } 
    protected IDataRepository DataRepository { get { return _dataRepository; } } 
    protected HttpContext Context { get { return _httpContext; } } 
    protected HttpRequest Request { get { return _httpContext.Request; } } 
    protected HttpResponse Response { get { return _httpContext.Response; } } 
    protected bool IsRequestFromUAD { get { return Request.UserAgent == null ? false : Request.UserAgent.Equals("UAD"); } } 
    public virtual bool IsReusable { get { return false; } } 

    public void ProcessRequest(HttpContext context) 
    { 
     WindsorContainer container = (WindsorContainer)context.Application[0]; 
     _logger = container.Resolve<ILogger>(); 
     _dataRepository = container.Resolve<IDataRepository>(); 

     _httpContext = context; 
     ProcessRequest(new HttpContextWrapper(context)); 
    } 

    protected virtual void ReturnResponse(HttpStatusCode httpStatus) 
    { 
     Response.StatusCode = (int)httpStatus; 
    } 

    protected virtual void ReturnResponse(HttpStatusCode httpStatus, string response) 
    { 
     Response.StatusCode = (int)httpStatus; 
     Response.Write(response); 
    } 

    protected virtual string GetInputStream() 
    { 
     using (var reader = new StreamReader(Request.InputStream)) 
     { 
      return reader.ReadToEnd(); 
     } 
    } 

    public abstract void ProcessRequest(HttpContextBase context); 
} 

Répondre

1

J'ai mal lu votre message. Ne tenez pas compte de cette réponse.

Je suis curieux lorsque vous appelez Dispose() sur votre dépôt cependant.

+0

Bonjour Frank. Merci pour votre commentaire. Si le BaseHttpHandler implémente IHttpHandler, la méthode ProcessRequest ne devrait-elle pas être appelée automatiquement? Lorsque j'exécute ce code en dehors des tests unitaires, cela fonctionne bien? – Matt

+0

Vous n'avez pas marqué ProcessRequest comme virtuel. Ainsi, lorsque le runtime a un pointeur vers votre classe en tant que BaseHttpRequest, il va essayer d'appeler BaseHttpRequest.ProcessRequest(). Lorsque votre test a un pointeur en tant que UADTimeHandler, il essayera d'appeler le UADTimeHandler.ProcessRequest(). Donc, ils ont un comportement différent. –

+0

Eh bien, je ne suis pas sûr de savoir pourquoi vous voyez ce comportement, puisque le runtime le référencera comme IHttpHandler et non comme BaseHttpHandler. Je me demande si votre test se comporterait différemment si UADHandlerFixture._handler était de type IHttpHandler au lieu de BaseHttpHandler. –