UnitTest на контроллере WebAPI с аутентификацией Windows - PullRequest
1 голос
/ 29 мая 2019

У меня есть API с несколькими методами. Мне нужно аутентифицировать пользователя с помощью Windows Authentication, прежде чем он попадет в любой из методов контроллера Чтобы добиться этого, я написал приватный метод, чтобы получить UserIdentity и присвоить его закрытой переменной bool.

Каждый из методов контроллера сначала проверяет bool для проверки пользователя, а в случае сбоя выдает 401 обратно во внешний интерфейс.

Пока я пишу тестовый блок для методов контроллера, я не уверен, как имитировать UserIdentity, или мне следует обновить контроллер таким образом, чтобы можно было проверить UserIdentity

Контроллер:

public class DefaultController : ApiController
{
  private bool isUsrAuthenticated;

  public DefaultController()
  {
    AuthenticateUser();
  }

  private void AuthenticateUser()
  {
    isUsrAuthenticated = User.Identity.IsAuthenticated;
  }

  [HttpGet]
  public IHttpActionResult GetProducts()
  {
    if (isUsrAuthenticated) { // do something }
    else { // throw 401 }
  }

  [HttpPost]
  public IHttpActionResult Update()
  {
    if (isUsrAuthenticated) { // do something }
    else { // throw 401 }
  }
}

Результаты модульного теста всегда возвращают 401.

1 Ответ

0 голосов
/ 29 мая 2019

Во время выполнения свойство ApiController.User устанавливается задолго после вызова конструктора контроллера. Это будет означать, что ваш текущий поток вызова его в конструкторе, как

public DefaultController() {
    AuthenticateUser();
}

имеет недостатки и не обеспечит ожидаемое поведение.

Давайте сначала исправим код, а затем посмотрим на модульный тест.

Используйте свойство вместо

private bool IsUserAuthenticated {
    get {
        return User.Identity.IsAuthenticated;
    }
}

и соответственно изменить код

public class DefaultController : ApiController {

    private bool IsUserAuthenticated {
        get {
            return User.Identity.IsAuthenticated;
        }
    }

    [HttpGet]
    public IHttpActionResult GetProducts() {
        if (IsUserAuthenticated) { // do something }
        else { // throw 401 }
    }

    [HttpPost]
    public IHttpActionResult Update() {
        if (IsUserAuthenticated) { // do something }
        else { // throw 401 }
    }

    //...

}

Теперь, для тестирования ApiController, свойство User может быть установлено при организации модульного теста, чтобы тест выполнялся как ожидалось

Например

[TestMethod()]
public void DefaultController_Should_GetProducts() {
    //Arrange
    var username = "name_here";
    var userId = 2;

    var identity = new GenericIdentity(username, "");
    identity.AddClaim(new Claim(ClaimTypes.NameIdentifier, userId.ToString()));
    identity.AddClaim(new Claim(ClaimTypes.Name, username));

    var principal = new GenericPrincipal(identity, roles: new string[] { });
    var user = new ClaimsPrincipal(principal);

    var controller = new DefaultController() {
        User = user //<-- Set the User on the controller directly
    };

    //Act
    var actionResult = controller.GetProducts();

    //Assert
    //...
}
...