2015-01-21 2 views
0

У меня возникла проблема издеваться над классом ApplicationUserManager, используя nsubstitute и nunit для тестирования моего метода действий. Вот как я издеваюсь над классом.Как мне высмеять ApplicationUserManager для модульного тестирования с использованием nsubstitute и nunit

var _userManager = Substitute.For<ApplicationUserManager>(); 

В моей тестируемой системе вводят класс, используя инъекцию конструктора. Когда я запускаю тест, я получаю это сообщение об ошибке.

Castle.DynamicProxy.InvalidProxyConstructorArgumentsException : Can not instantiate proxy of class: JobHub.Web.Identity.ApplicationUserManager. 
Could not find a parameterless constructor. 

Мой вопрос, как я правильно издеваться этот класс, используя NSubstitue, как я с помощью SetPhoneNumberAsync() метода класса.

EDIT Кстати, вот кусок кода, который я пытаюсь проверить

[HttpPost] 
     [ValidateAntiForgeryToken] 
     public async Task<ActionResult> Create(UserProfileView model) 
     { 
      if (ModelState.IsValid) 
      { 
       var userId = User.Identity.GetUserId(); 

       var profile = model.MapToProfile(userId); 

       if (CommonHelper.IsNumerics(model.PhoneNo)) 
       { 
        await _userManager.SetPhoneNumberAsync(userId, model.PhoneNo); 
       } 

       if (model.ProfileImage != null) 
       { 
        profile.ProfileImageUrl = await _imageService.SaveImage(model.ProfileImage); 
       } 

       _profileService.AddProfile(profile); 
       _unitofWork.SaveChanges(); 

       //Redirect to the next page (i.e: setup experiences) 
       return RedirectToAction("Skills", "Setup"); 
      } 
      return View("UserProfile", model); 
     } 

ответ

1

Эта ошибка возникает, когда substituting for a concrete class, но не были предоставлены необходимые аргументы конструктора. Если MyClass конструктор принимает два аргумента, он может быть заменен следующим образом:

var sub = Substitute.For<MyClass>(firstArg, secondArg); 

Пожалуйста, имейте в виду, что NSubstitute не может работать с не виртуальными методами, и при замене классов (а не интерфейсов) есть некоторые когда реальный код может быть выполнен.

Об этом поясняется ниже в Creating a substitute.

+0

Да, но как я могу создать замену реального класса, который не выполняет реальный код, а вместо этого вызывает только обратный вызов, переданный ему. Я попробовал его с помощью [когда-do-do callbacks] (http://nsubstitute.github.io/help/callbacks), хотя он вызывает обратный вызов, он все равно также вызывает реальный код. Если нет, может ли это быть достигнуто с помощью moq? – Cizaphil

+0

Код конструктора и код в виртуальных членах всегда будут работать. Я считаю, что Moq, FakeItEasy и RhinoMocks имеют схожие ограничения, хотя стоит проверить эти проекты и/или опубликовать общий вопрос .net mocking для SO. Лучший способ гарантировать, что реальный код не будет работать, - это использовать интерфейс (поскольку у них нет реального кода). Если вы не можете редактировать исходный класс, одним из вариантов является использование шаблона адаптера, чтобы исходный класс соответствовал интерфейсу. –

+0

Большое спасибо, я, наконец, разрешил проблему и прошел тест, издеваясь над «IUserStore » и «IUserPhoneNumberStore », используя метод расширения Moq и возвращая нужную 'Task '. Хотя это выглядит немного грязно, но это работает. – Cizaphil

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