c #: написание теста для этого варианта использования - PullRequest
0 голосов
/ 26 ноября 2011

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

Внутри пароля password.ResetUserPassword - я выясняю, какой пользователь запрашивает изменение пароля, если он может измениться, и генерирует электронное письмо, если это необходимо.Мне нужно передать User объекты этому методу?Эта логика вызывается моим контроллером (или, если нужно, бэкэндом)

    [Test]
    public void Test_If_New_Password_Is_Generated_For_User()
    {
        var repo = new ReadOnlySession();
        var update = new UpdateSession();

        var passwordService = new UserPasswordService();
        var password = new AccountProfileProcessor(repo, update, passwordService);

        password.ResetUserPassword("companyid", "jon.smithers", null);

        Assert.Pass();

    }

// Метод, который я вызываю

_ passwordService - это служба, которая обрабатывает генерацию новогоключ для пользователя

    public void ResetUserPassword(string identifier, string loginid, string passwordreseturl)
    {
        //get user object
        var currentUser = _readOnlySession.All<User>()
            .Where(x => x.Login == loginid)
            .SingleOrDefault(); //any other logic to get user resides here...

        if (currentUser == null)
            throw new UserNotFoundException();

        _passwordService.ResetPassword(currentUser.User, identifier, loginid);

        //persist data
        _updateSession.Update(currentUser.User);

        //send out email with the url as a link inside the email
    }

1 Ответ

1 голос
/ 26 ноября 2011

Что-то вроде следующего будет работать. (Мне пришлось сделать несколько предположений о ваших классах, и я до сих пор не уверен, что это за тип currentUser.User.)

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

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

Для меня этот метод делает слишком много - у него много обязанностей. Мучительная настройка теста и множественные проверки - это запах кода. Попробуйте разбить его на более мелкие методы (вероятно, все еще вызываемые из существующего метода), а затем протестировать их независимо. GetUser(loginId) (или throw) будет первым методом, который я извлечу. Перемещение некоторых из этих методов на службы (например, хранилище) упростит тестирование.

Уточнение - Вы упоминаете в комментариях, что хотите проверить, отличается ли PasswordKey. Это ответственность конкретного UserPasswordService. Вам нужно проверить это самостоятельно.

// Arrange

const string TestLogin = "jon.smithers";
User testUser = new User { Login = TestLogin };
var testUsers = new List<User> { testUser };

var mockUpdate = new Mock<IUpdateSession>();

var mockRepo = new Mock<IReadOnlySession>();
mockRepo.Setup(x => x.All<User>()).Returns(testUsers);

var mockPasswordService = new Mock<IUserPasswordService>();

var password = new AccountProfileProcessor(
    mockRepo.Object, mockUpdate.Object, mockPasswordService.Object);

// Act

password.ResetUserPassword("companyid", TestLogin, null);

// Assert

mockPasswordService.Verify(
    x => x.ResetPassword(
        It.IsAny<string>(), It.IsAny<string>(), TestLogin));

mockUpdate.Verify(x => x.Update(testUser));
...