2010-02-12 3 views
6

Когда модульное тестирование кодовой базы, каковы контрольные признаки того, что мне нужно использовать макетные объекты?Тестирование единиц измерения пустот/издевательства над предметными знаками

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

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

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

+0

Для вашего последнего пункта проверьте: http://martinfowler.com/articles/mocksArentStubs.html, чтобы убедиться, что вы знаете о различиях. – Finglas

+0

Вот хорошая прочитанная адресация на некоторые из этих вопросов: http://xunitpatterns.com/TestStrategy.html –

ответ

2

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

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

Пример:

[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 
} 

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

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

+4

Вы заканчиваете тест на привязку к внутренним деталям реализации с помощью макетов, которые означают, что они чаще ломаются. При проверке состояния вы заботитесь только о выходе. В целом, макеты, как правило, более беспорядочны, но они, безусловно, занимают свое место в модульном тестировании. – Finglas

-1

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

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

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

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

+0

-1 - Это основано на непонимании ложных ошибок и заглушек. В то время как вы, конечно же, используете функции TDD, это не то, для чего предназначены макеты. Вы не издеваетесь над тестируемым объектом, вы издеваетесь над его зависимостями. – TrueWill

+0

Да, я думаю, есть разница между окурками и издевательствами. Я думаю, вы неправильно поняли, что я сказал. В первом параграфе я описывал, что такое модульные тесты, и как вы можете использовать созданный вами объект, который имитирует реальный объект, к которому у вас нет доступа или к которому у вас нет доступа. Во втором абзаце я начал описывать, что макеты для тестирования интеграции ... но я был неправ. Тестирование интеграции выполняется после модульного тестирования и выполняется с помощью реальных объектов, а не издевок. В любом случае, макеты лучше всего использовать, когда вы хотите выполнить модульное тестирование, прежде чем интегрировать. –

0

Mocks/stub/fakes/test doubles/etc. хорошо разбираются в модульных тестах и ​​позволяют тестировать тестируемый класс/систему в изоляции. Тесты интеграции могут не использовать какие-либо макеты; они фактически попадают в базу данных или другую внешнюю зависимость.

Вы используете макет или заглушку, когда вам нужно. Как правило, это связано с тем, что класс, который вы пытаетесь протестировать, зависит от интерфейса. Для 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), и я только утверждать против тестируемой системы (экземпляр класса I» м). Я могу проверить значения свойств (состояние) или возвращаемое значение метода, как показывает этот случай.

Рекомендую прочитать The Art of Unit Testing, особенно если вы используете .NET.

Смежные вопросы