2014-06-11 18 views
5

User.Identity, Api Denetleyici sınaması ile alay etmeye çalışıyorum. Set User property for an ApiController in Unit Test Kullanıcı özelliğini ayarlamak için:Birim Testi Web Api 2 Mock Kullanıcısı

[Route(Urls.CustInfo.GetCustomerManagers)] 
    public HttpResponseMessage GetCustomerManagers([FromUri]int groupId = -1) 
    { 
     var user = User.Identity.Name; 
     if (IsStaff(user) && groupId == -1) 
     { 
      return ErrorMissingQueryStringParameter; 
     } 
     ... 
    } 

bu yazı öneriyi takip:

Bu benim API yöntemidir.

[TestMethod] 
    public void User_Without_Group_Level_Access_Call_GetCustomerManagers_Should_Fail() 
    { 
     Thread.CurrentPrincipal = new GenericPrincipal(new GenericIdentity("Bob", "Passport"), new[] {"managers"}); 
     var response = m_controller.GetCustomerManagers(); 

     Assert.AreEqual(HttpStatusCode.BadRequest, response.StatusCode); 
    } 

Ama testi çalıştırıldığında, Kullanıcı özelliği her zaman null:

Bu

benim testtir.

Hatta User.Identity çağrılmadan önce CurrentPrincipal'ı api yöntemine ayarlamak için satırı hareket ettirmeyi denedim, ancak yine de boş.

Neyi yanlış yapıyorum? Bu yaklaşım web api 2 için çalışmazsa, Kullanıcı özelliğini simüle etmek/alay etmek için en iyi yol nedir?

Teşekkürler!

cevap

13

Sen ControllerContext.RequestContext.Principal kullanıcıyı ayarlayabilirsiniz:

controller.ControllerContext.RequestContext.Principal = new GenericPrincipal(new GenericIdentity("Bob", "Passport"), new[] {"managers"}); 

Veya bir kısaltmadır eşdeğeri:

controller.User = new GenericPrincipal(new GenericIdentity("Bob", "Passport"), new[] {"managers"}); 
+1

Müdür'ü bu şekilde ayarladıktan sonra, UserId ayarlanmamış. Sistemin altında test mantığımın Userid'e bağlı olması nedeniyle ayarlanması gerekiyor. Örneğin. User.Identity.Name 'dolduruldu ("Bob"), ancak' User.Identity.GetUserId() '. – Bart

+0

@Bart bunu çözdünüz mü? –

+0

@Ben Hall Bir süredir var ama sanmıyorum. Benim çözümümün yalnızca 'UserId' yerine 'UserName' kullanmak için mantığı değiştirmek olduğunu düşünüyorum. – Bart

4

Web API 2'nin daha kolay birim test için, MyTested.WebApi kullanabilirsiniz. Ben en çok oyu alan cevapta verilen bir kullanıcı adı yerine() GetUserId için dönmek aslında ayarlanmış bir şeye bu çözmek için başardınız

MyWebApi 
    .Controller<WebApiController>() 
    .WithAuthenticatedUser(user => user.WithUsername("NewUserName")) 
    .Calling(c => c.SomeAction()) 
    .ShouldReturn() 
    .Ok(); 
0

: Burada doğrulanmış kullanıcı ile bir örnektir. İstediğim alay aracına FakeItEasy kullanımımdan oyu almak zorunda kalacağım için özür dilerim.

Claim claim = new Claim("", userId); 
ClaimsIdentity fakeClaimsIdentity = A.Fake<ClaimsIdentity>(); 
A.CallTo(() => fakeClaimsIdentity.FindFirst(A<string>.Ignored)).Returns(claim); 

IPrincipal fakeIPrincipal = A.Fake<IPrincipal>(); 
A.CallTo(() => fakeIPrincipal.Identity).Returns(fakeClaimsIdentity); 

var controller = new AuthorisedServicesController() 
{ 
     User = fakeIPrincipal 
}; 

daha iyi bir çözüm (Tekrar kod yazmak ise) soyut olacaktır Ancak ben o arama yapabilir bir nesne enjekte edebilir GetUserId çağırarak gerçek kod, bu kolayca mockable olmak. Bir fabrika gibi biraz.