2014-06-11 19 views
5

Sto provando a simulare User.Identity nel mio test Api Controller.Test unità Web Api 2 Mock User

Questo è il mio metodo API:

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

ho seguito il suggerimento in questo post: Set User property for an ApiController in Unit Test per impostare la proprietà dell'utente.

Questa è la mia prova:

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

Ma quando viene eseguito il test, la proprietà d'uso è sempre nullo.

Ho anche provato a spostare la linea per l'impostazione di CurrentPrincipal nel metodo API prima di chiamare User.Identity, ma è ancora nullo.

Cosa sto sbagliando? Se questo approccio non funziona per web api 2, qual è il modo migliore per simulare/prendere in giro la proprietà User?

Grazie!

risposta

13

È possibile impostare l'utente in ControllerContext.RequestContext.Principal:

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

O un equivalente scorciatoia:

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

Dopo aver impostato il preside in questo modo, l'ID utente non è impostato. Ho bisogno che sia impostato perché la logica nel mio sistema sotto test è basata su Userid. Per esempio. 'User.Identity.Name' è pieno (" Bob ") ma non' User.Identity.GetUserId() '. – Bart

+0

@Bart hai mai risolto questo? –

+0

@ Ben Hall È passato un po 'di tempo, ma non credo di averlo fatto. Penso che la mia soluzione fosse semplicemente cambiare la logica per usare 'UserName' invece di' UserId'. – Bart

4

Per facilitare test di unità di Web API 2, è possibile utilizzare MyTested.WebApi. Ecco un esempio di utente autenticato:

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

sono riuscito a risolvere questo effettivamente impostare qualcosa di tornare per GetUserID() in contrapposizione ad un nome utente indicato nella risposta con il maggior numero di voti. Mi scuso che oyu dovrà tradurre dal mio uso di FakeItEasy allo strumento di scherno di tua scelta.

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

Tuttavia una soluzione migliore (se stavo scrivendo di nuovo il codice) sarebbe quello di astrarre il codice vero e proprio chiamando GetUserID in modo da poter poi iniettare un oggetto che può fare quella chiamata, essendo questo facilmente mockable. Un po 'come una fabbrica.

Problemi correlati