Правильно Unit Test Service / Взаимодействие с репозиторием

У меня есть метод CreateAccount(...), который я хочу для модульного тестирования. Обычно он создает учетную запись и сохраняет ее в БД, а затем возвращает вновь созданную учетную запись. Я издеваюсь над хранилищем и ожидаю вызова Insert (...). Но метод Insert ожидает объект Account.

Этот тест проходит, но он не кажется правильным, потому что CreateAccount создает учетную запись, а я создаю учетную запись для ожидаемого вызова по образцу (два отдельных экземпляра учетной записи). Как правильно проверить этот метод? Или я создаю Аккаунты, используя этот метод, неправильно?

[Fact]
    public void can_create_account()
    {
        const string email = "test@asdf.com";
        const string password = "password";
        var accounts = MockRepository.GenerateMock<IAccountRepository>();
        accounts.Expect(x => x.Insert(new Account()));
        var service = new AccountService(accounts);

        var account = service.CreateAccount(email, password, string.Empty, string.Empty, string.Empty);

        accounts.VerifyAllExpectations();
        Assert.Equal(account.EmailAddress, email);
    }

А вот и метод CreateAccount:

public Account CreateAccount(string email, string password, string firstname, string lastname, string phone)
    {
        var account = new Account
                          {
                              EmailAddress = email,
                              Password = password,
                              FirstName = firstname,
                              LastName = lastname,
                              Phone = phone
                          };

        accounts.Insert(account);
        return account;
    }

1 ответ

Решение
[Test]
public void can_create_account()
{
    const string email = "test@asdf.com";
    const string password = "password";

    Account newAcc = new Account();
    var accounts = MockRepository.GenerateMock<IAccountRepository>();

    var service = new AccountService(accounts);
    var account = service.CreateAccount(email, password, string.Empty, 
                                        string.Empty, string.Empty);

    accounts.AssertWasCalled(x => x.Insert(Arg<Account>
                            .Matches(y => y.EmailAddess == email 
                                       && y.Password == password)));                   

    Assert.AreEqual(email, account.EmailAddress);
    Assert.AreEqual(password, account.Password);
}

Итак, то, что вы тестируете здесь, по сути является фабричным методом (то есть он создает новый экземпляр объекта и возвращает его). Единственный известный мне способ тестирования таких методов - это проверка того, что мы получили возвращенный объект со свойствами, которые ожидаем (последние два вызова Assert.Equal выше делают это). У вас есть дополнительный вызов в хранилище в вашем методе; и поэтому нам нужен дополнительный вызов AssertWasCalled со сравнением свойств, как описано выше (чтобы убедиться, что правильный экземпляр объекта был использован в качестве параметра для этого вызова).

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