2009-08-21 9 views
10

Voglio mockup IPrincipal così ho fatto questoCome configurare IPrincipal per un mockup?

public Mock<IPrincipal> Principal { get; set; } 

nella mia messa a punto della mia NUnit

Principal = new Mock<IPrincipal>(); 

Quindi questo dovrebbe essere tutto ciò che ho bisogno nella mia NUnit test di unità, ma come circa nel mio attuale file del controller?

Come faccio a configurarlo?

Per esempio io ho un membership.Provider

Quindi quello che ho fatto è stato nel mio costruttore di controllo che ho fatto

Provider = Membership.Provider; 

Allora nel mio controller ho appena usato Provider. (Qualunque cosa ho bisogno).

Non sono sicuro di come impostare il Principal allo stesso modo.

risposta

20

Stai parlando di ASP.NET MVC? Credo di si.

È necessario creare un'istanza del controller e impostarne il RequestContext. È deridere il HttpContext del RequestContext, e all'interno di questa HttpContext, è deridere la sua proprietà per l'utente, e impostare fino al vostro deriso IPrincipal:

var principal = new Moq.Mock<IPrincipal>(); 
// ... mock IPrincipal as you wish 

var httpContext = new Moq.Mock<HttpContextBase>(); 
httpContext.Setup(x => x.User).Returns(principal.Object); 
// ... mock other httpContext's properties, methods, as needed 

var reqContext = new RequestContext(httpContext.Object, new RouteData()); 

// now create the controller: 
var controller = new MyController(); 
controller.ControllerContext = 
    new ControllerContext(reqContext, controller); 

Spero che questo aiuti.

EDIT:

Cordiali saluti, la proprietà utente sul classe Controller deriva dall'oggetto HttpContext, come potete vedere qui (questo è il metodo getter per la proprietà d'uso, ottenuta da riflettore - è possibile scaricare ASP il codice sorgente .NET MVC pure):

public IPrincipal User 
{ 
    get 
    { 
     if (this.HttpContext != null) 
     { 
      return this.HttpContext.User; 
     } 
     return null; 
    } 
} 

Se ora si controlla la proprietà HttpContext, si vedrà:

public HttpContextBase HttpContext 
{ 
    get 
    { 
     if (base.ControllerContext != null) 
     { 
      return base.ControllerContext.HttpContext; 
     } 
     return null; 
    } 
} 

Quindi, tutto ciò che fino ad ora è stata "leggere solo". E abbiamo bisogno di un modo per "iniettare" un "Utente" deriso. Quindi, controlliamo che possiamo effettivamente iniettare un oggetto ControllerContext sul controller attraverso una proprietà. Verifichiamo come sta ottenendo la sua "HttpContext" oggetto, per sapere come deridere correttamente in su:

public virtual HttpContextBase HttpContext 
{ 
    get 
    { 
     if (this._httpContext == null) 
     { 
      this._httpContext = (this._requestContext != null) ? this._requestContext.HttpContext : new EmptyHttpContext(); 
     } 
     return this._httpContext; 
    } 
    set 
    { 
     this._httpContext = value; 
    } 
} 

Quindi, qui vediamo che l'oggetto ControllerContext ottiene è HttpContext da un oggetto RequestContext. In modo che potrebbe spiegare quello che ho fatto in precedenza:

  1. Mock un IPrincipal con i dati desiderati,
  2. Mock un HttpContext, e alimentarlo con l'IPrincipal,
  3. Mock un RequestContext, e alimentarlo con la HttpContext,
  4. Creare un'istanza del controller e impostare la proprietà ControllerContext sull'oggetto RequestContext deriso.

Dopo tutta questa magia, il controller non ha idea che lo si chiami senza una connessione effettiva effettuata tramite un server Web.

Quindi, è possibile continuare a utilizzare la proprietà "Utente" all'interno del controller come al solito, non è necessario apportare modifiche.

+0

Come apparirebbe la classe del controller attuale? – chobo2

+1

Cosa intendi? Dovrebbe essere un controller "normale", con azioni. Che cosa vuoi testare esattamente? –

+0

Beh, non posso lasciare il codice nel mio controller in questo modo User.Identity.Name poiché nel mio mockup se io non lo configuro e lo passo un po 'come nel mio controller (per iniezione di proprietà o iniezione del costruttore) non sarà deriso. Vedo il tuo passaggio qualcosa di reContext in Controller-context thign e il controller ma non capisco nemmeno cosa sia. – chobo2

Problemi correlati