2009-08-21 8 views
10

Chcę makieta IPrincipal więc zrobiłem toJak skonfigurować IPrincipal do makiet?

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

w mojej konfiguracji mojego NUnit

Principal = new Mock<IPrincipal>(); 

Więc to powinno być wszystko, co potrzebne w moim badanej jednostki NUnit ale co w moim rzeczywisty plik kontrolera?

Podobnie jak skonfigurować?

Na przykład mam membership.Provider

Więc co zrobiłem było w moim konstruktora kontrolera zrobiłem

Provider = Membership.Provider; 

Więc w moim kontrolera I właśnie używane Provider. (Co mi potrzeba).

Nie jestem pewien, jak skonfigurować główne zadanie w ten sam sposób.

Odpowiedz

20

Czy mówisz o ASP.NET MVC? Tak myślę.

Musisz utworzyć instancję kontrolera i ustawić jego RequestContext. Drwicie HttpContext z RequestContext, a wewnątrz tego HTTPContext, drwicie swoją własność użytkownika i ustawić go na swojej wyśmiewali 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); 

nadzieję, że to pomaga.

EDIT:

FYI, obiekt Użytkownik od klasy Controller pochodzi od obiektu HttpContext, jak można zobaczyć tutaj (jest to metoda getter dla właściwości użytkownika, otrzymanego z odbłyśnikiem - można pobrać ASP Kod źródłowy MVC również):

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

Jeśli teraz sprawdzić właściwość HTTPContext, widać:

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

tak, wszystko do tej pory było „czytać tylko". I potrzebujemy sposobu na "wstrzyknięcie" wyśmiewanego "użytkownika". Sprawdzamy więc, czy możemy faktycznie wprowadzić obiekt ControllerContext na kontrolerze za pośrednictwem właściwości. Sprawdzamy jak to jest uzyskanie jego „HTTPContext” obiektu, aby wiedzieć, jak prawidłowo go mock up:

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

Tak, tutaj widzimy, że obiekt ControllerContext uzyskuje to HttpContext z obiektu RequestContext. Tak, że może wyjaśnić co zrobiłem powyżej:

  1. Mock IPrincipal z danych, które chcesz,
  2. Mock HttpContext i karmić je z IPrincipal,
  3. Mock RequestContext i karmić je z HttpContext,
  4. Utwórz instancję kontrolera i ustaw właściwość ControllerContext na wyszydzany obiekt RequestContext.

Po tym wszystkim magii, kontroler nie będzie miał pojęcia, że ​​wywołujesz go bez faktycznego połączenia za pośrednictwem serwera internetowego.

Możesz dalej normalnie korzystać ze swojej właściwości "Użytkownik" w kontrolerze, nie należy wprowadzać żadnych zmian.

+0

Jak wyglądałaby aktualna klasa kontrolera? – chobo2

+1

Co masz na myśli? Powinien to być "normalny" kontroler z akcjami. Co dokładnie chcesz przetestować? –

+0

Cóż, nie mogę po prostu zostawić kodu w moim kontrolerze, tak jak to User.Identity.Name, ponieważ w mojej makiecie, jeśli nie ustawiam tego i przekazuję trochę jak do mojego kontrolera (przez wstrzyknięcie własności lub wstrzyknięcie konstruktora) nie będzie kpiny. Widzę, jak przekazujesz coś w temacie reContext do kontrolera-kontekstu i kontrolera, ale nawet nie rozumiem, co to jest. – chobo2

Powiązane problemy