Mock IIdentity и IPrincipal
Я просто хочу спросить, что лучше всего подходит для поставки этих объектов в моих модульных тестах.
В моем unit test я тестирую объект CSLA. Объект CSLA внутренне использует одно свойство и один метод объекта ApplicationUser. ApplicationUser наследуется от IPrincipal.
Свойства:
1) ApplicationContext.User.IsInRole(...) - метод является частью IPrincipal
2) ApplicationContext.User.Identity.Name - имя является свойством IIdentity, которое является частью ApplicationUser aka IPricipal
Пример моего теста (с использованием 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
}
}
У меня есть небольшая проблема со вторым значением, именем. Я попытался издеваться над этим, но у меня возникли проблемы с назначением отладчика IIdentity для ApplicationUser, поскольку это делается внутренне.
Мне сказали просто создать некоторую IIPrincipal (в том числе IIdentity) самостоятельно, а не издеваться над ней вообще. Что можно сделать наверняка. Не уверен, что это можно назвать Stub, используя?
Так вы можете посоветовать мне, как бороться с IPrincipal и IIdentity? Любое предложение приветствуется.
Ответы
Ответ 1
Причина, по которой вы получаете ошибку нулевой ссылки, состоит в том, что IPrincipal.Identity
имеет значение null; он еще не установлен в вашем издеваемом IPrincipal
. Вызов .Name
null Identity
приводит к вашему исключению.
Ответ, как указал Карлтон, состоит в том, чтобы высмеять IIdentity
и установить его для возврата "ju" для своего свойства Name
. Затем вы можете сказать IPrincipal.Identity
вернуть mock IIdentity
.
Вот расширение вашего кода, чтобы сделать это (используя Rhino Mocks, а не Stubs):
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);
}
}
Ответ 2
Вот код, который я использую, чтобы вернуть тестового пользователя (используя Stubs):
[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;
}
У меня есть linq в другом коде, поэтому я использую тип var для переменных; просто замените правильные типы (IPrincipal, IIdentity), если это необходимо.