Заменяет ли Moq стандартное тестирование VS 'Assert'? - PullRequest
4 голосов
/ 06 октября 2010

Я пытаюсь понять, как использовать Moq, однако у меня возникает путаница относительно того, для чего нужно использовать Moq.Насколько я понимаю, фиктивные рамки используются для создания объектов, которые было бы трудно создать в обычных условиях.Однако примеры Moq, которые я видел, похоже, не только создают объект Moq, но и предоставляют методы для тестирования объектов - это, по-видимому, устраняет необходимость использования обычных методов Assert и т. Д., Которые мы используем для большинства модульных тестов.

Может ли кто-нибудь подтвердить, правильно ли я считаю, что Moq заменяет Assert и т. Д., Или я полностью упускаю точку Moq?

Ответы [ 2 ]

4 голосов
/ 07 октября 2010

Фреймворк, такой как Moq, не полностью заменяет Assert фреймворка тестирования. иногда это так, иногда нет.

Давайте сначала проведем различие между издевательствами и окурками. Заглушки используются исключительно для изоляции и для введения какого-либо контролируемого поведения в тестируемую систему (SUT).

Моты - это расширенный набор заглушек, и они могут проверить, было ли вызвано что-то на макете. В Moq вызов Verify() делает заглушку насмешкой в ​​отношении этого метода. Вызов VerifyAll() делает все методы, которые были установлены, ложными.

Рекомендуемый подход заключается в том, что в вашем тесте должно быть не более одного макета. В этом смысле это похоже на Assert - вы не должны проверять более чем одну вещь в тесте.

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

public interface IAccountRepository {
  decimal GetBalance(int accountId);
  void SetBalance(int accountId, decimal funds);
}

public class DepositTransaction {

  IAccountRepository m_repo;

  public DepositTransaction(IAccountRepository repo) {
    m_repo = repo;
  }

  public decimal DepositedFunds {get; private set;};

  void Deposit(int accountId, decimal funds) {
    decimal balance = m_repo.GetBalance(accountId);
    balance += funds;
    m_repo.SetBalance(balance);

    DepositedFunds += funds;
  }
}

public class DepositTest {
  [TestMethod]
  void DepositShouldSetBalance() {
    var accountMock = new Mock<IAccountRepository>();
    accountMock.Setup(a=>a.GetBalance(1)).Returns(100); //this is a stub with respect to GetBalance

    var transation = new DepositTransaction(accountMock.Object);
    transation.Deposit(1, 20);

    accountMock.Verify(a=>a.SetBalance(1, 120)); //this is a mock with respect to SetBalance
  }
  [TestMethod]
  void DepositShouldIncrementDepositedFunds() {
    var accountMock = new Mock<IAccountRepository>();
    accountMock.Setup(a=>a.GetBalance(1)).Returns(100); //this is a stub with respect to GetBalance

    var transation = new DepositTransaction(accountMock.Object);
    transation.Deposit(1, 20);
    transation.Deposit(1, 30);

    Assert.AreEqual(50, transaction.DepositedFunds);

  }
}
2 голосов
/ 08 октября 2010

+ 1 на Q и другие A ...

(повторяя очень полный ответ Игоря). Библиотека Mocking - это просто инструмент, используемый в тесте / спецификации, иногда выполняющий роль заглушки или макета.

Пересмешка на основе записи / воспроизведения часто может заменить роль Assert s в ваших тестах. Этот стиль был недавно подчеркнут в RhinoMocks (я полагаю, что 4.0 собирался отвлечь его в сторону), и в течение довольно долгого времени активно поощрялся в Moq. Я верю, что это то, что заставило тебя задать вопрос.

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

  • Будьте читабельны для вас, программистов по техническому обслуживанию, и практически для всех, кому когда-либо придется отлаживать или извлекать информацию из тестового кода
  • Утверждают как можно меньше вещей
  • Не перекрывается с другими тестами
  • Не будьте хрупкими - тесты не должны прерываться по случайным причинам, когда вы изменяете что-то, только косвенно связанное с вашим тестом. В контексте Moqing и насмешек это означает отклонение от строгих издевательств в большинстве случаев
  • Сделайте как можно меньше работы, чтобы доказать свою точку зрения
  • Четкое разделение на разделы Arrange / Context, Act и Assert

Последний пункт здесь критический - вам нужен один бит, где вы делаете проверки, и он должен быть последним Assert. Иногда это может означать, что вы можете даже выполнить Setup вызов в Moq на этапе Arrange / Context, а затем убедиться, что он использовался на этапе Assert с кодом, похожим на дублирование.

...