Модульный тест MVC4 и аутентификация Windows

Насколько я вижу, если мое приложение mvc4 не использует проверку подлинности Windows (и поэтому мои контроллеры не пытаются читать объекты User), когда я создаю свой экземпляр контроллера из TestMethod, объект User остается нулевым. Так что мои тесты не пройдены. Что я могу сделать, чтобы заставить их работать?

Дополнительная информация: Это мой тест:

[TestMethod]
public void Create()
{
   var ctrl = new LanguageController();
   var res = ctrl.Manage() as ViewResult;
   Assert.IsNotNull(res);
   Assert.AreEqual(res.ViewName, "Create");
}

А у моего LanguageController есть базовый класс:

public class LanguageController : MyController
{

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

public class MyController : Controller
  {
     protected Rights rm;
     public MyController()
     {
        this.rm = RightManager.Discover(User.Identity);
     }

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

1 ответ

Хорошо, у вас есть несколько проблем с вашим модульным тестом, и я рассмотрю их, объясняя, почему пользователь является нулевым.

Это просто потому, что вы не предоставили заглушенную версию экземпляра User (IPrincipal). Так что вам нужно найти способ внедрить это в ваш контроллер. Важно, чтобы вы вывели как можно больше зависимостей в свой контроллер, чтобы он не был чистым контроллером для работы, а также, что немаловажно, улучшал тестируемость.

Что бы я сделал, чтобы ввести зависимости, как показано ниже.

Ваше SUT (тестируемая система)

public class MyController : Controller
{
    protected Rights rm;
    public MyController(IPrincipal user, IRightManager rightManager)
    {
        this.rm = rightManager.Discover(user.Identity);
    }
}

public class LanguageController : MyController
{
    public LanguageController(IPrincipal user, IRightManager rightManager)
        : base(user, rightManager)
    { 
    }

    public ActionResult Manage()
    {
        return View("Manage");
    }
}

Это дает мне возможность ввести поддельного пользователя, а также поддельного правого менеджера.

Итак, как бы вы получили настоящий пользователь Right Manager при запуске приложения во время выполнения?

Вы можете внедрить зависимости в контроллер при создании контроллера.

Если вы не используете инфраструктуру внедрения зависимостей (в идеале, вы должны это делать), вы все равно можете вводить зависимости вручную. Например, создавая свойство в вашем контроллере и вставляя реальный экземпляр в контроллер, а во время модульного тестирования внедряйте поддельный экземпляр и т. Д. Я не буду вдаваться в подробности, так как немного отклоняюсь - но вы можете найти много SO вопросы / веб-ссылки в отношении этого аспекта.

Ваш юнит-тест Теперь у вас есть способ внедрить ваши зависимости, вы можете легко внедрить их из вашего юнит-теста. Вы можете либо использовать платформу Isolation (AKA и Mock Object Framework), либо вы можете внедрить их как в старом школьном стиле, то есть написанные от руки mocks / fakes/stubs. Я предлагаю использовать каркас изоляции. Создание ручных подделок, вводит ненужное дублирование кода и проблему обслуживания. Поскольку я не знаю, какой фреймворк вы предпочитаете, я создал несколько рукописных фальшивок / издевательств / заглушек.

public class FakeRightManager : IRightManager {
    public Rights Discover(IIdentity identity) {
        return new Rights();
    }
}

public class MyFakeIdentity : IIdentity {
    public string AuthenticationType {
        get { throw new NotImplementedException(); }
    }

    public bool IsAuthenticated {
        get { throw new NotImplementedException(); }
    }

    public string Name {
        get { throw new NotImplementedException(); }
    }
}

public class MyFakePrincipal : IPrincipal {
    public IIdentity Identity {
        get { return new MyFakeIdentity(); }
    }

    public bool IsInRole(string role) {
        throw new NotImplementedException();
    }
}

Вы юнит тест:

    [TestMethod]
    public void ManageAction_Execute_ReturnsViewNameManager()
    {
        var fakeUser = new MyFakePrincipal();
        var fakeRightManager = new FakeRightManager();
        var ctrl = new LanguageController(fakeUser, fakeRightManager);

        var res = ctrl.Manage() as ViewResult;

        Assert.AreEqual<string>(res.ViewName, "Manage");
    } 

В своем тесте вы проверяете Assert.IsNotNull(res); это не обязательно, как если бы res равнялся нулю, ваш второй assert в любом случае потерпит неудачу.

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

Другие вопросы по тегам