3

Я пытаюсь выполнить тестирование этого метода контроллера, который выходит из коробки в текущих проектах MVC.Интерфейсы для издевательств ConfirmEmailAsync и другие методы UserManager в MVC5

[AllowAnonymous] 
public async Task<ActionResult> ConfirmEmail(string userId, string code) 
{ 
    if (userId == null || code == null) 
    { 
     return View("Error"); 
    } 
    var result = await UserManager.ConfirmEmailAsync(userId, code); 
    return View(result.Succeeded ? "ConfirmEmail" : "Error"); 
} 

AccountController имеет конструктор, который будет принимать ApplicationUserManager и ApplicationSignInManager в качестве параметров и свойств сопоставления с частными сеттеров использовать для тестирования. Тем не менее, я не могу понять, как высмеять метод ConfirmEmailAsync.

Вы можете издеваться различные интерфейсы в пространстве имен идентичности:

var store = new Mock<IUserStore<ApplicationUser>>(); 

store.As<IUserEmailStore<ApplicationUser>>() 
      .Setup(x => x.FindByIdAsync("username1")) 
      .ReturnsAsync((ApplicationUser)null); 

var mockManager = new ApplicationUserManager(store.Object); 

AccountController ac = new AccountController(mockManager, null, GetMockRepository().Object, GetMockLogger().Object); 

Но я не могу найти или выяснить, какой интерфейс мне нужно для того, чтобы создать макет из ConfirmEmailAsync.

Как это сделать? И для справки, есть ли хороший способ узнать, какие интерфейсы эти методы включены, чтобы имитировать и проверить их?

+0

Я обошел это, абстрагировав большую часть функциональности идентичности в своем собственном проекте, чтобы я мог легко тестировать его и повторно использовать абстракцию в других проектах. Я начал с этой статьи http://timschreiber.com/2015/01/14/persistence-ignorant-asp-net-identity-with-patterns-part-1/, а затем настроил ее в соответствии с моими потребностями – Nkosi

ответ

2

ConfirmEmailAsync В настоящее время этот компонент не является частью интерфейса. Он находится в классе UserManager<TUser, TKey>, который является базовым классом Framework Identity.

Мое решение?

Абстрактных все вещи

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

Persistence-Ignorant ASP.NET Identity with Patterns

Я тогда точно выверенная идеи, чтобы удовлетворить свои потребности. Я в основном просто поменял все, что мне нужно, от asp.net.identity для моих пользовательских интерфейсов, которые более или менее отражали функциональность, предоставляемую инфраструктурой, но с преимуществом более простой имитации.

IIdentityUser

/// <summary> 
/// Minimal interface for a user with an id of type <seealso cref="System.String"/> 
/// </summary> 
public interface IIdentityUser : IIdentityUser<string> { } 
/// <summary> 
/// Minimal interface for a user 
/// </summary> 
public interface IIdentityUser<TKey> 
    where TKey : System.IEquatable<TKey> { 

    TKey Id { get; set; } 
    string UserName { get; set; } 
    string Email { get; set; } 
    bool EmailConfirmed { get; set; } 
    string EmailConfirmationToken { get; set; } 
    string ResetPasswordToken { get; set; } 
    string PasswordHash { get; set; } 
} 

IIdentityManager

/// <summary> 
/// Exposes user related api which will automatically save changes to the UserStore 
/// </summary> 
public interface IIdentityManager : IIdentityManager<IIdentityUser> { } 
/// <summary> 
/// Exposes user related api which will automatically save changes to the UserStore 
/// </summary> 
public interface IIdentityManager<TUser> : IIdentityManager<TUser, string> 
    where TUser : class, IIdentityUser<string> { } 
/// <summary> 
/// Exposes user related api which will automatically save changes to the UserStore 
/// </summary> 
public interface IIdentityManager<TUser, TKey> : IDisposable 
    where TUser : class, IIdentityUser<TKey> 
    where TKey : System.IEquatable<TKey> { 

    Task<IIdentityResult> AddPasswordAsync(TKey userid, string password); 
    Task<IIdentityResult> ChangePasswordAsync(TKey userid, string currentPassword, string newPassword); 
    Task<IIdentityResult> ConfirmEmailAsync(TKey userId, string token); 
    //...other code removed for brevity 
} 

IIdentityResult

/// <summary> 
/// Represents the minimal result of an identity operation 
/// </summary> 
public interface IIdentityResult : System.Collections.Generic.IEnumerable<string> { 
    bool Succeeded { get; } 
} 

В моей реализации по умолчанию менеджера идентичности я просто завернул ApplicationManager, а затем сопоставляются результаты и функциональность между моими типами и asp.net.identity ty ПЭС.

public class DefaultUserManager : IIdentityManager { 
    private ApplicationUserManager innerManager; 

    public DefaultUserManager() { 
     this.innerManager = ApplicationUserManager.Instance; 
    } 
    //..other code removed for brevity 
    public async Task<IIdentityResult> ConfirmEmailAsync(string userId, string token) { 
     var result = await innerManager.ConfirmEmailAsync(userId, token); 
     return result.AsIIdentityResult(); 
    } 
    //...other code removed for brevity 
} 
0

Отказ от ответственности: Я работаю на Typemock.

На самом деле вам не нужен какой-либо интерфейс, если вы используете Typemock, вам просто нужно подделать требуемый IdentityResult и изменить поведение асинхронного метода «ConfirmEmailAsync», например тест, который проверяет сценарий неподтвержденного электронная почта:

[TestMethod, Isolated] 
public async Task TestWhenEmailIsBad_ErrorMessageIsShown() 
{ 

    // Arrange 
    // Create the wanted controller for testing and fake IdentityResult 
    var controller = new aspdotNetExample.Controllers.AccountController(); 
    var fakeIdentityRes = Isolate.Fake.Instance<IdentityResult>(); 

    // Fake HttpContext to return a fake ApplicationSignInManager 
    var fakeSIM = Isolate.WhenCalled(() => controller.UserManager).ReturnRecursiveFake(); 

    // Modifying the behavior of ConfirmEmailAsync to return fakeIdentityRes 
    Isolate.WhenCalled(() => fakeSIM.ConfirmEmailAsync("", "")).WillReturn(Task.FromResult<IdentityResult>(fakeIdentityRes)); 
    Isolate.WhenCalled(() => fakeIdentityRes.Succeeded).WillReturn(false); 

    // Act 
    var result = await controller.ConfirmEmail("", "") as ViewResult; 

    // Assert 
    Assert.AreEqual("Error", result.ViewName); 
}  
Смежные вопросы