2016-06-02 3 views
4

У меня есть следующий код:Mocking UserManager

var clientId = this.UserManager.FindById(this.User.Identity.GetUserId()).ClientId; 

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

Проблема заключается в том, что он выбрасывает исключение с использованием нулевой ссылки, поскольку UserManager.FindById возвращает null. Если я могу издеваться над этим, значит у него есть свойство ClientId, я смогу избежать исключения.

Что я пробовал? Первый насмехаясь сам UserManager:

var fakeUserManager = new Mock<ApplicationUserManager>(); 
    fakeUserManager.Setup(x => x.FindById(It.IsAny<string>())) 
    .Returns(user); 

Но когда я пытаюсь установить мой controller.UserManager к нему:

controller.UserManager = fakeUserManager.Object; 

Visual Studio говорит, что UserManager не может быть использована в этом контексте, поскольку множество аксессору является недоступным.

Я решил создать пользователя с помощью UserManager, но метод create снова приводит к исключению нулевой ссылки.

Это как ApplicationUserManager получить настройки:

public ApplicationUserManager UserManager 
     { 
      get 
      { 
       return _userManager ?? Request.GetOwinContext().GetUserManager<ApplicationUserManager>(); 
      } 
      private set 
      { 
       _userManager = value; 
      } 
     } 

Решение:

Благодаря @mason ответ я был в состоянии решить эту проблему. Я опубликую решение как редактирование, потому что в решении есть определенные вещи, которые не были включены в вопрос и ответ. Во-первых, поскольку @mason предположил, что я сделал установщика свойства UserManager общедоступным.

public ApplicationUserManager UserManager 
     { 
      get 
      { 
       return _userManager ?? Request.GetOwinContext().GetUserManager<ApplicationUserManager>(); 
      } 

      set 
      { 
       _userManager = value; 
      } 
     } 

Во-вторых, и это разная часть. Я был в состоянии создать новый ApplicationUserManager и передать его пользователю по насмешливый IUserStore:

var store = new Mock<IUserStore<User>>(MockBehavior.Strict); 

      store.As<IUserStore<User>>() 
      .Setup(x => x.FindByIdAsync(It.IsAny<string>())) 
      .ReturnsAsync(user); 

var manager = new ApplicationUserManager(store.Object); 

Тогда я просто установить controller.UserManager:

controller.UserManager = manager; 

Примечание: Переменная user помогает мне для передачи пользователю, имеющему ClientId, контроллеру.

+0

Как создать свойство 'UserManager' в контроллере в первую очередь? Через конструктор? – mason

ответ

1

Вы не можете установить свойство UserManager, потому что вы сделали setter приватным. Сделайте это общедоступным.

public ApplicationUserManager UserManager 
{ 
    get 
    { 
     return _userManager ?? Request.GetOwinContext().GetUserManager<ApplicationUserManager>(); 
    } 
    set 
    { 
     _userManager = value; 
    } 
} 

Теперь вы сможете установить свойство UserManager вашего контроллера.

+0

Отличный ответ, в сочетании с некоторыми другими изменениями мне удалось заставить его работать, но у меня есть несколько вопросов. Хорошо ли публиковать магазин? Это плохая практика? И это повлияет на безопасность приложения? – StefanL19

+1

@ StefanL19 Публичные и частные [модификаторы доступа] (https://msdn.microsoft.com/en-us/library/wxh6fsc7.aspx). Они не являются функциями безопасности. Они предназначены для того, чтобы помочь вам в создании библиотеки, которая предоставляет только необходимые функции, чтобы вы случайно не злоупотребляли кодом.Это организационная вещь, а не функция безопасности. – mason

Смежные вопросы