Подтвердить что ты не робот

Написание 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 только для этого.

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

4b9b3361

Ответ 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()
   {
   }
}

Ответ 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;