2012-02-13 12 views
12

Jestem bardzo nowe do testów jednostkowych i staram się pisać test na całkiem prosty sposób:Jak wykonać test jednostkowy, aby przetestować metodę, która sprawdza nagłówki żądań?

public class myClass : RequireHttpsAttribute 
{ 
    public override void OnAuthorization(AuthoizationContext filterContext) 
    { 
     var request = filterContext.HttpContext.Request; 
     var header = Convert.ToBoolean(request.Headers["Special-Header-Name"]); 

     if (!(header || request.IsSecureConnection)) 
     { 
      HandleNonHttpsRequest(filterContext); 
     } 
    } 
} 

Ta metoda, która dziedziczy z RequireHttpsAttribute, sprawdza, czy dany nagłówek jest obecny ze strony , jeśli go brakuje lub jest ono fałszywe, a strona nie jest bezpieczna, wówczas zadzwoni pod numer HandleNonHttpsRequest, w przeciwnym razie nie zrobi nic.

Do testowania używamy Moq i Nunit. Znalazłem kilka zasobów, aby pomóc w budowaniu fałszywego HttpContext z Moq, ale szczerze mówiąc nie jestem pewien, jak go używać lub gdzie przejść w moich testach jednostkowych, aby upewnić się, że fałszywe HttpContexts są lub nie powodują wywołania metody HandleNonHttpsRequest.

Naprawdę doceniam wszelkie wskazówki dotyczące tego problemu.

Odpowiedz

20
// arrange 
var context = new Mock<HttpContextBase>(); 
var request = new Mock<HttpRequestBase>(); 
var headers = new NameValueCollection 
{ 
    { "Special-Header-Name", "false" } 
}; 
request.Setup(x => x.Headers).Returns(headers); 
request.Setup(x => x.HttpMethod).Returns("GET"); 
request.Setup(x => x.Url).Returns(new Uri("http://www.example.com")); 
request.Setup(x => x.RawUrl).Returns("/home/index"); 
context.Setup(x => x.Request).Returns(request.Object); 
var controller = new Mock<ControllerBase>(); 

var actionDescriptor = new Mock<ActionDescriptor>(); 
var controllerContext = new ControllerContext(context.Object, new RouteData(), controller.Object); 
var filterContext = new AuthorizationContext(controllerContext, actionDescriptor.Object); 
var sut = new myClass(); 

// act 
sut.OnAuthorization(filterContext); 

// assert 
Assert.IsInstanceOfType(filterContext.Result, typeof(RedirectResult)); 
var redirectResult = (RedirectResult)filterContext.Result; 
Assert.AreEqual("https://www.example.com/home/index", redirectResult.Url); 
+1

+1 dla wskazując sekcje testu AAA. – CodingWithSpike

+0

Dziękujemy! To wysłało mnie we właściwym kierunku, aby uzyskać pewne udane testy. – Dredj

1

Tak, użyłbym Moq i utworzę Mock<AuthorizationContext>. Będziesz potrzebował serii fałszywych obiektów do skonfigurowania fałszywego żądania, w szczególności do określenia NameValueCollection fałszywych nagłówków.

var request = new Mock<HttpRequestBase>(); 
request.SetupGet(c => c.Headers).Return(new NameValueCollection{ /* initialize values here */}); 
request.SetupGet(c => c.IsSecureConnection).Return(/*specify true or false depending on your test */); 

var httpContext = new Mock<HttpContextBase>(); 
httpContext.SetupGet(c => c.Request).Return(request.Object); 


var filterContext = new Mock<AuthorizationContext>(); 
filterContext.SetupGet(c => c.HttpContext).Return(httpContext.Object); 

var myclass = new myClass(); 
myClass.OnAuthorization(filterContext.Object); 

(przepraszam jeśli składnia lub użycie jest nieco off; robi to od szczytu głowy)

może trzeba iść i drwić żadnych dodatkowych członków na filterContext że HandleNonHttpsRequest powołuje. Mam dwa zalecenia, aby o tym porozmawiać, ponieważ czasami może to być kłopotliwe, jeśli testowana metoda wykonuje wiele skomplikowanych czynności w sprawie filterContext: 1) sprawdź wizualnie, a jeśli jest wystarczająco prosty, wyśmiewaj wszystkie przywołane fragmenty 2) stwórz test myClass.OnAuthorizationRequest, ale nie implementuj żadnego kodu jeszcze innego niż wywołanie HandleNonHttpsRequest. Kontynuuj test i naprawiaj brakujące/niepoprawnie wyśmiewane elementy, dopóki test nie przejdzie. Następnie zaimplementuj swoją rzeczywistą logikę dla OnAuthorizationRequest, testując i naprawiając (powtórzyć płukanie), aż przejdzie.

0

I napotkał problem z the accepted solution użyciu ASP.NET MVC 4. Aby rozwiązać mi szydzili atrybut przedmioty kontekst http inaczej sut.OnAuthorization było przyczyną obiekt jest niezdefiniowany wyjątek:

MockHttpContext.Setup(x => x.Items) 
    .Returns(new System.Collections.Generic.Dictionary<object, object>()); 
Powiązane problemy