Написание модульных тестов для методов, использующих пользователей.Идентичности.Имя в Интернете ASP.NET API-интерфейс


Я пишу тестовые случаи, используя модульный тест для ASP.NET веб-API.

Теперь у меня есть действие, которое вызывает некоторый метод, определенный мной на уровне сервиса, где я использовал следующую строку кода.

string username = User.Identity.Name;
// do something with username
// return something

Теперь, как я создаю метод модульного теста для этого, я получаю нулевые ссылочные исключения. Я вроде как новичок в написании юнит-тестов и прочего.

И я хочу использовать модульный тест только для этого.

Пожалуйста, помогите мне с этим. Спасибо.

8 36

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()
   {
   }
}

Это мое решение.

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;