Написание Unit Test для методов, которые используют User.Identity.Name в веб-интерфейсе ASP.NET
Я пишу тестовые примеры, используя Unit Test для веб-API ASP.NET.
Теперь у меня есть действие, которое вызывает вызов некоторого метода, который я определил на уровне службы, где я использовал следующую строку кода.
string username = User.Identity.Name;
// do something with username
// return something
Теперь, как я создаю метод Unit Test для этого, я получаю исключения для нулевой ссылки. Я новичок в написании Unit Test и прочее.
И я хочу использовать Unit Test только для этого.
Пожалуйста, помогите мне в этом. Спасибо.
Ответы
Ответ 1
Ниже приведен только один способ сделать это:
public class FooController : ApiController {
public string Get() {
return User.Identity.Name;
}
}
public class FooTest {
[Fact]
public void Foo() {
var identity = new GenericIdentity("tugberk");
Thread.CurrentPrincipal = new GenericPrincipal(identity, null);
var controller = new FooController();
Assert.Equal(controller.Get(), identity.Name);
}
}
Ответ 2
Вот еще один способ, который я нашел в учебнике по тестированию NerdDinner
. Он работал в моем случае:
DinnersController CreateDinnersControllerAs(string userName)
{
var mock = new Mock<ControllerContext>();
mock.SetupGet(p => p.HttpContext.User.Identity.Name).Returns(userName);
mock.SetupGet(p => p.HttpContext.Request.IsAuthenticated).Returns(true);
var controller = CreateDinnersController();
controller.ControllerContext = mock.Object;
return controller;
}
[TestMethod]
public void EditAction_Should_Return_EditView_When_ValidOwner()
{
// Arrange
var controller = CreateDinnersControllerAs("SomeUser");
// Act
var result = controller.Edit(1) as ViewResult;
// Assert
Assert.IsInstanceOfType(result.ViewData.Model, typeof(DinnerFormViewModel));
}
Убедитесь, что вы прочитали полный раздел: Издевательство над свойством User.Identity.Name
Он использует фреймворк Moq
, который вы можете установить в своем Test project
с помощью NuGet: http://nuget.org/packages/moq
Ответ 3
С WebApi 5.0 это немного отличается. Теперь вы можете:
controller.User = new ClaimsPrincipal(
new GenericPrincipal(new GenericIdentity("user"), null));
Ответ 4
Ничего из этого не получилось для меня, я использовал решение по другому вопросу, который использует Moq для настройки имени пользователя в ControllerContext: fooobar.com/questions/151266/...
Ответ 5
Здесь я нашел решение для другого способа, как установить идентификатор пользователя для тестирования уровня контроллера из тестового метода.
public static void SetUserIdentityName(string userId)
{
IPrincipal principal = null;
principal = new GenericPrincipal(new GenericIdentity(userId),
new string[0]);
Thread.CurrentPrincipal = principal;
if (HttpContext.Current != null)
{
HttpContext.Current.User = principal;
}
}
Ответ 6
Если у вас много контроллеров для тестирования, я бы предложил создать базовый класс, а в конструкторе создайте GenericIdentity
и GenericPrincipal
и установите Thread.CurrentPrincipal
GenericPrincipal principal = new GenericPrincipal(new
GenericIdentity("UserName"),null); Thread.CurrentPrincipal = principal;
Затем наследуем этот класс.. Таким образом, каждый класс Unit Test будет иметь набор объектов типа
[TestClass]
public class BaseUnitTest
{
public BaseUnitTest()
{
GenericPrincipal principal = new GenericPrincipal(new GenericIdentity("UserName"),null);
Thread.CurrentPrincipal = principal;
}
}
[TestClass]
public class AdminUnitTest : BaseUnitTest
{
[TestMethod]
public void Admin_Application_GetAppliction()
{
}
}
Ответ 7
Когда я запускаю Unit test - в моем случае он использует проверку подлинности Windows и Identity.Name - это мое доменное имя, которое я также хочу изменить для теста.
Поэтому я использую такой подход с "взломом" вещей, которые я хочу в IAuthenticationFilter
Ответ 8
Это мое решение.
var claims = new List<Claim>
{
new Claim(ClaimTypes.Name, "Nikita"),
new Claim(ClaimTypes.NameIdentifier, "1")
};
var identity = new ClaimsIdentity(claims);
IPrincipal user = new ClaimsPrincipal(identity);
controller.User = user;