2015-02-24 4 views
4

Я пишу тестовый пример, чтобы проверить поведение объекта.Thread.sleep в тестовом примере JUnit

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

Я разработал тест, Junit так:

@Test(expected = IllegalStateException.class) 
public void testCallAfterTimeout() { 
    MyObject o= new MyObject(); 
    //To ensure the timeout is occurred 
    Thread.sleep(1000); 
    o.call(); 
} 

Как вы думаете, это хорошая практика, или я должен следовать другой подход?

Большое спасибо

+1

Почему вы хотите это сделать в первую очередь? – virendrao

+2

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

+0

Как намекают выше, один вопрос - почему ваш другой объект ведет себя так? Но, откладывая это, этот подход кажется прекрасным, хотя он довольно грубовато; 1000 мс значительно длиннее 500 мс, –

ответ

7

Есть две проблемы, связанные с использованием (реального) времени в тестовых случаях:

  1. Он действительно никогда не детерминированным. Особенно, если вы ищете высокую точность, тестовые камеры будут успешными в 95% случаев. Но иногда они терпят неудачу, это самые сложные типы отладки. Обратите внимание, что при использовании Thread.sleep() в многопоточном тестовом примере это еще сложнее.
  2. Тестовые чехлы с сонами занимают много времени, и через некоторое время это приведет к тому, что ваш полный набор тестов будет громоздким.

Если вы хотите, чтобы ваш путь был приемлемым. Но есть и другие варианты:

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

@Test(expected = IllegalStateException.class) 
public void testCallAfterTimeout() { 
    MyObject o= new MyObject(); 
    // Example function that you could make 
    advanceClock(1000, TimeUnit.MILLISECONDS) 
    o.call(); 
} 

В вашем объекте вы должны вводить часы. MyObject может выглядеть следующим образом:

class MyObject 
{ 

    public MyObject() 
    { 
      this(new Clock()); 
    } 

    // Protected so only the test case can access it 
    protected MyObject(Clock clock) 
    { 
      // Save clock as local variable, store creation time etc. 
    } 
} 

В Java 8 предусмотрен механизм для этого, смотри, например, LocalDate.now(). Но вы также можете легко реализовать свою собственную тишину. Обратите внимание, что часы Java 8 обеспечивают extra mechanisms, чтобы автоматически увеличивать время, когда оно используется.

1

Независимо от того, какой смысл его, и что вы на рожон ....

Что делать, если вы решили, что тайм-аут необходим, чтобы после 60minutes больше появляться, вы ждать ваших тест один час? Тайм-аут должен быть параметром вашего объекта MyObject, поэтому вы можете установить его на небольшое значение для тестирования (или даже 0, чтобы заставить allwas таймаут при тестировании).

Во-вторых, если вы хотите действительно иметь проверенные связанные с временем функции, время и тайм-аут следует обрабатывать отдельно от вашей основной логики (класс MyObject). Например, у вас может быть класс Timekeeper с mehtod canCallMethod(), который вызывается классом MyObject (и он устанавливается по его построению). Таким образом, в вашем тесте вы инициализируете свой класс MyObject своей реализацией Timekeeper, которая возвращает true или false, и убедитесь, что ваш класс MyObject ведет себя так, как ожидалось. MyObject может иметь конструктор по умолчанию, который всегда использует «реальный» тайм-аут, поэтому внешний мир не является силой для работы с внутренними функциями Timekeeper.

+0

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

+0

Это личный вкус, но мне не нравятся частичные издевательства, так как насмешливые методы тестируемого объекта чувствуют себя неправильно и предполагают, что такая логика может быть делегирована где-то в другом месте == переустроена. – Zielu

+0

Я думаю, что к тестированию следует подходить с прагматической точки зрения: дать оценку тестированию долю бюджета сложности, но держать ее на минимуме. Поэтому, если есть возможность излить метод стратегии внутри тестируемого объекта, непременно возьмите его. Имейте в виду, что сама сложность вызывает проблемы с обслуживанием и правильностью, это те тесты, которые необходимы для защиты вас. –

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