Написание модульных тестов для методов, использующих пользователей.Идентичности.Имя в Интернете ASP.NET API-интерфейс
Я пишу тестовые случаи, используя модульный тест для ASP.NET веб-API.
Теперь у меня есть действие, которое вызывает некоторый метод, определенный мной на уровне сервиса, где я использовал следующую строку кода.
string username = User.Identity.Name;
// do something with username
// return something
Теперь, как я создаю метод модульного теста для этого, я получаю нулевые ссылочные исключения. Я вроде как новичок в написании юнит-тестов и прочего.
И я хочу использовать модульный тест только для этого.
Пожалуйста, помогите мне с этим. Спасибо.
8 ответов:
Ниже приведен только один способ сделать это:
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); } }
Вот еще один способ, который я нашел в учебнике по тестированию
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
С WebApi 5.0 это немного отличается. Теперь вы можете сделать:
controller.User = new ClaimsPrincipal( new GenericPrincipal(new GenericIdentity("user"), null));
Ничего из этого не сработало для меня, я использовал решение по другому вопросу, который использует Moq для настройки имени пользователя в ControllerContext: https://stackoverflow.com/a/6752924/347455
Здесь я нашел решение для другого способа, как установить имя идентификатора пользователя для тестирования уровня контроллера из метода тестирования.
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; } }
Когда я запускаю модульный тест - в моем случае он использует проверку подлинности Windows и Identity.Name это мое доменное имя, которое я также хочу изменить для теста. Поэтому я использую такой подход с "взломом" вещей, которые я хочу в IAuthenticationFilter
Если у вас есть много контроллеров для тестирования, то я бы предложил создать базовый класс и в конструкторе создать
GenericIdentity
&GenericPrincipal
и множествоThread.CurrentPrincipal
GenericPrincipal principal = new GenericPrincipal(new GenericIdentity("UserName"),null); Thread.CurrentPrincipal = principal;
Затем Унаследуйте этот класс .. Таким образом, каждый класс модульного теста будет иметь набор объектов принципа
[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() { } }