Mock IIdentity e IPrincipal
-
03-07-2019 - |
Domanda
Voglio solo chiedere quale sarebbe l'approccio migliore per fornire questi oggetti nei miei test unitari.
Nel mio unit test sto testando l'oggetto CSLA. L'oggetto CSLA utilizza internamente una proprietà e un metodo dell'oggetto ApplicationUser. ApplicationUser è ereditato da IPrincipal. Le proprietà sono: 1) ApplicationContext.User.IsInRole (...) - il metodo fa parte di IPrincipal 2) ApplicationContext.User.Identity.Name - il nome è proprietà di IIdentity che fa parte di ApplicationUser aka IPricipal
Esempio del mio test (usando RhinoMock):
public void BeforeTest()
{
mocks = new MockRepository();
IPrincipal mockPrincipal = mocks.CreateMock<IPrincipal>();
ApplicationContext.User = mockPrincipal;
using (mocks.Record()) {
Expect.Call(mockPrincipal.IsInRole(Roles.ROLE_MAN_PERSON)).Return(true);
Expect.Call(mockPrincipal.Identity.Name).Return("ju"); //doesn't work!!!! return null ref exc
}
}
Ho un leggero problema con il secondo valore, il nome dell'identità. Ho provato a prenderlo in giro, ma ho problemi ad assegnare IIdentity beffardo a ApplicationUser, poiché è fatto internamente. Mi è stato detto di creare solo un IIPrincipal (incluso IIdentity) da solo e di non deriderlo affatto. Che può essere fatto di sicuro. Non sono sicuro se questo può essere chiamato come Stub utilizzando?
Quindi mi puoi consigliare su come affrontare IPrincipal e IIdentity? Qualsiasi suggerimento è il benvenuto.
Soluzione
Il motivo per cui ricevi un errore di riferimento null è perché IPrincipal.Identity
è null; non è stato ancora impostato nel tuo IPrincipal
deriso. La chiamata a .Name
il Identity
null comporta la tua eccezione.
La risposta, come ha sottolineato Carlton, è di deridere IIdentity
anche , e impostarlo per restituire "ju " per la sua proprietà Name
. Quindi puoi dire a IPrincipal.Identity
di restituire il finto IIdentity
.
Ecco un'espansione del tuo codice per farlo (usando Rhino Mocks anziché Stub):
public void BeforeTest()
{
mocks = new MockRepository();
IPrincipal mockPrincipal = mocks.CreateMock<IPrincipal>();
IIdentity mockIdentity = mocks.CreateMock<IIdentity>();
ApplicationContext.User = mockPrincipal;
using (mocks.Record())
{
Expect.Call(mockPrincipal.IsInRole(Roles.ROLE_MAN_PERSON)).Return(true);
Expect.Call(mockIdentity.Name).Return("ju");
Expect.Call(mockPrincipal.Identity).Return(mockIdentity);
}
}
Altri suggerimenti
Ecco il codice che uso per restituire un utente test (usando Stub):
[SetUp]
public void Setup()
{
var identity = MockRepository.GenerateStub<IIdentity>();
identity.Stub(p => p.Name).Return("TestUser").Repeat.Any();
var principal = MockRepository.GenerateStub<IPrincipal>();
principal.Stub(p => p.Identity).Return(identity).Repeat.Any();
Thread.CurrentPrincipal = principal;
}
Ho linq in altri codici, quindi sto usando il tipo var per le variabili; basta sostituire i tipi corretti (IPrincipal, IIdentity) se necessario.