2015-07-31 2 views
1

Выполнение этого теста:JMockit насмешливый System.currentTimeMillis()

@Test 
public void testSystemCurrentTimeMillis() { 
    new NonStrictExpectations(System.class) {{ 
     System.currentTimeMillis(); result = 1438357206679L; 
    }}; 
    long currentTime = System.currentTimeMillis(); 
    assertEquals(1438357206679L, currentTime); 
} 

Я получаю IllegalStateException:

 
java.lang.IllegalStateException: Missing invocation to mocked type at this point; please make sure such invocations appear only after the declaration of a suitable mock field or parameter 
    at unittests.DateTest$1.(DateTest.java:24) 
    at unittests.DateTest.testSystemCurrentTimeMillis(DateTest.java:23) 

Что случилось с моим Теста (JMockit 1,18)?

+0

Что является результатом? можете ли вы поделиться всем кодом класса. Также что такое NonStrictExpectations ??? вы также можете поделиться этим кодом. – StackFlowed

+0

NonStrictExpectations - класс JMockit. результат используется для JMockit. http://jmockit.org/tutorial/Mocking.html#expectation – trunkc

+0

Я всегда использую org.joda.time.DateTimeUtils для получения текущего времени DateTimeUtils.currentTimeMillis() и в модульном тесте DateTimeUtils.setCurrentMillisFixed (longValue) в конце DateTimeUtils. setCurrentMillisSystem() – StackFlowed

ответ

1

Как и многие вещи с JMockit, это достаточно легко сделать. Попробуйте это ..

@Test 
public void testSystemCurrentTimeMillis(@Mocked final System unused) { 
    new NonStrictExpectations() {{ 
     System.currentTimeMillis(); result = 1438357206679L; 
    }}; 
    long currentTime = System.currentTimeMillis(); 
    assertEquals(1438357206679L, currentTime); 
} 

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

+0

Принял ваш ответ, но я только хотел высмеять метод currentTimeMillis(), а не весь класс System. Кажется, это ошибка в JMockit. – trunkc

+1

@trunkc Это не ошибка, а ограничение «частичной насмешки»: она не может обрабатывать «родные» методы, такие как 'System.currentTimeMillis()'.Это ограничение, однако, применимо только к API ожиданий; вы можете высмеять только желаемый метод 'native', создав' MockUp '(который использует API Mockups). –

+0

Вы должны добавить подсказку об этом ограничении в учебнике. – trunkc

1

Эта вещь была введена в JMockit версии 1.17 использовать только ссылку на объект с NonStrictExpectation() {} блок, Устарел значение атрибута для Передразнивало

Устаревшие «стоимость» атрибут @Mocked, который используется для «статического» частичного издевательства. Существующие применения следует заменить на «динамическое» частичное издевательство, передав экземпляр или класс, чтобы частично издеваться над вызовом конструктора Expectations (Object ...) или путем применения класса MockUp.

Пожалуйста, обратитесь на ссылку ниже: JMockit version history

+0

Я не использую атрибут value @Mocked. – trunkc

2

Мое окончательное решение заключается в создании макете для системы, что издевается только метод currentTimeMillis():

private static class SystemMock extends MockUp<System> { 
    @Mock 
    public static long currentTimeMillis() { 
     return 10000000L; 
    } 
} 

@Test 
public void testAddNowDate() { 
    new SystemMock(); 
    long currentTime = System.currentTimeMillis(); 
    assertEquals(10000000L, currentTime); 
} 
+0

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

+0

@ Rogério заботиться о разработке? Как проверить функциональность, зависящую от системных часов, без издевательства над ней? – KidCrippler

+0

Код, которому требуется текущее время, должен использовать тип более высокого уровня ('java.util.Date',' java.time.LocalDate' и т. Д.), А не 'currentTimeMillis()'. И тогда он должен позволять передавать объекты даты/времени из кода клиента, а не всегда получать текущее время. Если, конечно, вам не понадобится текущее системное время в миллисекундах/секундах. Как я уже сказал, вызов 'System.currentTimeMillis()' вполне может быть проблемой дизайна, но я не могу точно знать это без дополнительной информации. –

0

Да, это частично насмешливо. С небольшой коррекции в nonStrictExpectation() {} ваш приведенный выше код может также получить исправление:

@Mocked 
private System system; 

new NonStrictExpectations() {{ 
    System.currentTimeMillis(); 
    result = 1438357206679L; 
}}; 

долго CURRENTTIME = System.currentTimeMillis(); assertEquals (1438357206679L, currentTime);

Это также должно работать.

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