Модульное тестирование пустых методов / сигнальных знаков объекта-объекта - PullRequest
6 голосов
/ 13 февраля 2010

При модульном тестировании кодовой базы, каковы контрольные признаки того, что мне нужно использовать фиктивные объекты?

Будет ли это так же просто, как видеть множество вызовов других объектов в базе кода?

Кроме того, как бы я мог тестировать методы, которые не возвращают значения? Так что, если метод возвращает void, но печатает в файл, я просто проверяю содержимое файла?

Насмешка для внешних зависимостей, так что это буквально все, нет? Файловая система, БД, сеть и т.д ...

Ответы [ 3 ]

2 голосов
/ 13 февраля 2010

Во всяком случае, я, вероятно, чрезмерно использую издевательства.

Когда класс делает вызов другому, обычно я высмеиваю этот вызов и проверяю, что вызов был сделан с правильными параметрами. В противном случае у меня будет модульный тест, который проверяет, работает ли конкретный код вычеркнутого объекта.

Пример:

[Test]
public void FooMoo_callsBarBaz_whenXisGreaterThan5()
{
    int TEST_DATA = 6;
    var bar = new Mock<Bar>();
    bar.Setup(x => x.Baz(It.Is<int>(i == TEST_DATA)))
       .Verifiable();

    var foo = new Foo(bar.Object);

    foo.moo(TEST_DATA);

    bar.Verify();
}

...
[Test]
public void BarBaz_doesSomething_whenCalled()
{
   // another test
}

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

Я предпочитаю небольшие краткие тесты. Легче писать, легче поддерживать, легче понять цель теста.

0 голосов
/ 19 февраля 2010

издевается / заглушки / подделки / тест удваивается / и т.д. хороши в модульных тестах и ​​позволяют тестировать класс / систему в тесте изолированно. Интеграционные тесты могут не использовать какие-либо макеты; они фактически попадают в базу данных или другую внешнюю зависимость.

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

Очень простой случай:

public class ClassToTest
{
   public ClassToTest(IDependency dependency)
   {
      _dependency = dependency;
   }

   public bool MethodToTest()
   {
      return _dependency.DoSomething();
   }
}

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

// Arrange

var mock = new Mock<IDependency>();

mock.Setup(x => x.DoSomething()).Returns(true);

var systemUnderTest = new ClassToTest(mock.Object);

// Act

bool result = systemUnderTest.MethodToTest();

// Assert

Assert.That(result, Is.True);

Обратите внимание, что я делаю тестирование состояния (как предложил @Finglas) и я утверждаю только против тестируемой системы (экземпляр класса, который я тестирую). Я мог бы проверить значения свойств (состояние) или возвращаемое значение метода, как показано в этом случае.

Я рекомендую прочитать Искусство модульного тестирования , особенно если вы используете .NET.

0 голосов
/ 19 февраля 2010

Модульные тесты предназначены только для одного фрагмента кода, который работает автономно внутри самого себя. Это означает, что он не зависит от других объектов для выполнения своей работы. Вы должны использовать mocks, если вы делаете тестовое программирование или тестовое программирование. Вы должны создать макет (или заглушку, как мне нравится его называть) функции, которую вы будете создавать, и установить определенные условия для прохождения теста. Первоначально функция возвращает значение false, и тест завершается неудачно, что и ожидается ... затем вы пишете код для выполнения реальной работы, пока он не пройдет.

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

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

Вы должны стараться всегда возвращать значение, если это возможно. Иногда вы сталкиваетесь с проблемами, когда вы уже что-то возвращаете, но в C и C ++ вы можете иметь выходные параметры, а затем использовать возвращаемое значение для проверки ошибок.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...