Как начать тестирование (jMock) - PullRequest
7 голосов
/ 25 мая 2010

Я пытаюсь научиться писать тесты.Я также изучаю Java, мне сказали, что я должен изучать / использовать / практиковать jMock, я нашел несколько статей в Интернете, которые в определенной степени помогают, например:

http://www.theserverside.com/news/1365050/Using-JMock-in-Test-Driven-Development

http://jeantessier.com/SoftwareEngineering/Mocking.html#jMock

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

Официальная документация по меньшей мере неопределенна и слишком сложна для меня.У кого-нибудь есть лучший способ узнать это.Хорошие книги / ссылки / учебники очень мне помогут.спасибо

РЕДАКТИРОВАТЬ - более конкретный вопрос:

http://jeantessier.com/SoftwareEngineering/Mocking.html#jMock - из этой статьи

Попробовал это издеваться над этимпростой класс:

import java.util.Map;
    public class Cache {
        private Map<Integer, String> underlyingStorage;
        public Cache(Map<Integer, String> underlyingStorage) {
            this.underlyingStorage = underlyingStorage;
        }
        public String get(int key) {
            return underlyingStorage.get(key);
        }
        public void add(int key, String value) {
            underlyingStorage.put(key, value);
        }
        public void remove(int key) {
            underlyingStorage.remove(key);
        }
        public int size() {
            return underlyingStorage.size();
        }
        public void clear() {
            underlyingStorage.clear();
        }
    }

Вот как я пытался создать тест / макет:

public class CacheTest extends TestCase {

    private Mockery context;
    private Map mockMap;
    private Cache cache;

    @Override
    @Before
    public void setUp() {
        context = new Mockery() {
            {
                setImposteriser(ClassImposteriser.INSTANCE);
            }
        };

        mockMap = context.mock(Map.class);
        cache = new Cache(mockMap);
    }

    public void testCache() {
        context.checking(new Expectations() {{
            atLeast(1).of(mockMap).size(); 
            will(returnValue(int.class));
        }});

    }
}

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

Ответы [ 4 ]

5 голосов
/ 25 мая 2010

Вот руководство по использованию JUnit и EasyMock (библиотека-макет, которую я лично считаю гораздо более простой в использовании, чем JMock): http://www.michaelminella.com/testing/unit-testing-with-junit-and-easymock.html

Даже если вы на 100% посвящены использованию JMock, понятия между ними одинаковы, и это должно помочь вам лучше понять их.

Цель насмешки заключается в том, что при тестировании класса A, который зависит от B и C, ваш тест A использует макетные версии B и C, чтобы иметь возможность указать их точное поведение, а не использование реальных реализаций B и C в вашем тесте A. В противном случае вы тестируете не только единицу A, но и неявно тестируете B и C.

4 голосов
/ 27 мая 2010

Как автор JMock, я бы не начал с этой техники, пока у вас не будет опыта работы с TDD. Просто начните с основ и работайте. Как только вы начнете испытывать трудности с масштабированием и развитием дизайна, вернитесь к технике.

Книга Дэйва Астелса - все еще хорошее введение, и я думаю, что это единственное из того поколения, которое хорошо объясняет насмешки. После этого вы можете (гм) рассмотреть наше «Растущее объектно-ориентированное программное обеспечение, руководствуясь тестами»

Не обращайте внимания на тех, кто говорит, что все дело в том, чтобы тесты с файловой системой проходили быстрее.

2 голосов
/ 25 мая 2010

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

Прямой тест может быть (я предполагаю, что вы используете JUnit 4 - ваш код является странной смесью JUnit 3 и 4

@Test
public void sizeIs0WhenEmpty()
{
  Map<Integer, String> map = Collections.emptyMap();
  Cache cache = new Cache(map)
  assertEquals(0, cache.size());
}

с макетами было бы (при условии, что макет корректен - я не использую JMock)

@Test
public void sizeIs0WhenEmpty()
{
  context.checking(new Expectations() {{
                   atLeast(1).of(mockMap).size(); 
                   will(returnValue(0));
                   }});
  assertEquals(0, cache.size());
}

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

Я бы рекомендовал вам прочитать о JUnit , прежде чем продолжить.

1 голос
/ 25 мая 2010

Я не знаю, как далеко вы продвинулись по пути изучения использования фиктивных объектов в тестировании, поэтому я напишу краткое описание, а затем укажу вам направление статьи, которая может быть вам полезна. Поддельные объекты используются в модульном тестировании для замены внешних зависимостей, которые сложно создать или которые трудно получить в состояние, в котором вы хотите их использовать для своего теста. Существующие различные фальшивые фреймворки предоставляют вам механизмы для создания «поддельных» объектов, которые заменяют эти зависимости. Эти фиктивные объекты будут отслеживать входящие в них вызовы из вашего кода и позволят вам позже утверждать об этих взаимодействиях. Есть хорошо известная статья о фиктивных объектах и ​​их связи с «заглушками», еще одной распространенной стратегией тестирования для упрощения внешних зависимостей. Он был написан Мартином Фаулером и его можно найти здесь:

http://martinfowler.com/articles/mocksArentStubs.html

...