2013-06-25 3 views
0

Я хочу проверить поведение частного метода. Метод «moveDataToArchive» выполняет 4 шага.JMockit - Строгое ожидание игнорируется

Это 4x: рассчитать дату + вызвать метод sub.

Это мой тест:

@Test 
    public void testMoveData2Archive() throws Exception{ 

    final long now = 123456789000L; 

    //Necessary to make the archivingBean runable. 
    Vector<LogEntry> logCollector = new Vector<LogEntry>(); 
    Deencapsulation.setField(archivingBean, "logCollector", logCollector); 

    new NonStrictExpectations(archivingBean) { 
     {  //Lets fake the DB stuff. 
      invoke(archivingBean, "getConnection");result = connection; 
      connection.prepareStatement(anyString); result = prepStatement; 
      prepStatement.executeUpdate(); returns(Integer.valueOf(3), Integer.valueOf(0), Integer.valueOf(3)); 
     } 
    }; 

    new NonStrictExpectations(props) { 
     { //This is important. The numbers will be used for one of each 4 submethods 
      props.getProperty(ArchivingHandlerBean.ARCHIVING_CREDMATURITY_OVER_IN_DAYS); result = "160"; 
      props.getProperty(ArchivingHandlerBean.ARCHIVING_CREDHIST_AGE_IN_DAYS); result = "150"; 
      props.getProperty(ArchivingHandlerBean.ARCHIVING_DEBTHIST_AGE_IN_DAYS); result = "140"; 
      props.getProperty(ArchivingHandlerBean.ARCHIVING_LOG_AGE_IN_DAYS); result = "130"; 
     } 
    }; 

    new Expectations() { 
     { 
      Date expected = new Date(now - (160 * 24 * 60 * 60 * 1000)); 
      invoke(archivingBean, "moveCreditBasic2Archive", expected); 

      expected = new Date(now - (150 * 24 * 60 * 60 * 1000)); 
      invoke(archivingBean, "moveCreditHistory2Archive", expected); 

      expected = new Date(now - (999 * 24 * 60 * 60 * 1000)); 
      invoke(archivingBean, "moveDebtorHistory2Archive", expected); 

      expected = new Date(now - (130 * 24 * 60 * 60 * 1000)); 
      invoke(archivingBean, "moveLog2Archive", expected); 

     } 
    }; 

    Calendar cal = Calendar.getInstance(); 
    cal.setTimeInMillis(now); 
    Deencapsulation.invoke(archivingBean,"moveDataToArchive",cal, props); 
} 

Что проблема? См. Третью ожидаемую дату. Это неверно! (999 вместо 140). Я также изменил порядок вызовов. Я даже сделал эти частные методы публичными и попробовал. Все эти изменения не изменили результат: Тест зеленый.

Что здесь не так? Почему тест зеленый?

ответ

0

Тест неправильно использует насмешливый API, смешивая строгие и нестрогие ожидания для того же макета (archivingBean). Первые ожидания, записанные на этом макете, не строгие, поэтому JMockit считает это нестрогим макетом для всего теста.

Правильный способ записи теста состоял бы в том, чтобы превратить строгий блок ожидания (тот, который с 4 вызовами «вспомогательные методы») в блок проверки в конце теста.

(В целом, у всего теста есть несколько проблем. 1) В общем, частные методы должны проверяться косвенно через какой-либо публичный метод. 2) Кроме того, частные методы не следует издеваться над ними, если в этом нет веской причины - в этом случае я, вероятно, напишу тест, который проверяет фактическое содержимое выходного файла. 3) Не издевайтесь над ненужными, например, props - props.setProperty, я полагаю. 4) Использовать авто-бокс - Integer.valueOf(3) ->3).

+0

Я попытался изменить строгое ожидание на проверку и получил еще одну ошибку. См. Мой «ответ» – KFleischer

0

@ Rogério: Ваши предположения не работают полностью. то есть у меня нет setProperty(). Я попытался использовать блок проверок.

К сожалению, я не понимаю, JMockit достаточно хорошо, чтобы он работает ...

Я сделал 2 вещи. Сначала я попытался издеваться над четырьмя частными методами. Я только хочу посмотреть, вызваны ли они. Но я не хочу, чтобы там была логика. Я попробовал его, расширяя первый NonStrictExpectations-Block, как это:

new NonStrictExpectations(archivingBean) { 
     { 
      invoke(archivingBean, "getConnection");result = connection; 
      connection.prepareStatement(anyString); result = prepStatement; 
      prepStatement.executeUpdate(); returns(Integer.valueOf(3), Integer.valueOf(0), Integer.valueOf(3)); 
      //New part 
      invoke(archivingBean, "moveCreditBasic2Archive", withAny(new Date())); 
      invoke(archivingBean, "moveCreditHistory2Archive", withAny(new Date())); 
      invoke(archivingBean, "moveDebtorHistory2Archive", withAny(new Date())); 
      invoke(archivingBean, "moveLog2Archive", withAny(new Date())); 
     } 
    }; 

С другой стороны, я переместил предпосылки блок вниз и сделал его проверку блока. Теперь JUnit завершается с

mockit.internal.MissingInvocation: Missing invocation of: 
de.lpm.ejb.archiving.ArchivingHandlerBean#moveCreditBasic2Archive(java.util.Date pOlderThan) 
with arguments: Tue Feb 03 03:39:51 CET 2009 
on mock instance: [email protected] 
at de.lpm.ejb.archiving.ArchivingHandlerBean.moveCreditBasic2Archive(ArchivingHandlerBean.java:175) 
[...] 
Caused by: Missing invocation 

Это линия 170-175 в ArchivingHandlerBean.java:

170: Connection connection = getConnection(); 
171: SQLService service = new SQLService(connection); 
172:    
173: PreparedStatement prepStmtMove = null; 
174:    
175: Vector<HashMap<String, String>> where_clauses = new Vector<HashMap<String,String>>(); 

Я просто хочу, чтобы убедиться, что 4 частные методы выполняются с правой датой.

+0

Да, мой ответ был не совсем правильным, потому что этот тест делает * частичным * насмешкой. Итак, в этом случае ожидания должны быть записаны первыми, чтобы JMockit не знал * не * для выполнения исходных реализаций метода. Блок проверки еще может быть написан позже, чтобы убедиться, что вызовы произошли, как ожидалось, но это означало бы избыточный код в тесте.В конце концов, насмешка просто не является хорошим выбором для этого теста, из-за необходимости вызывать/издеваться над частными методами и использовать частичное издевательство. Лично я бы использовал совершенно другой подход. –

+0

Не могли бы вы описать, как бы вы могли проверить эту ситуацию? – KFleischer

+0

Я бы использовал один из двух возможных альтернативных подходов: 1) написать тест черного ящика с внешними входами («реквизит» и т. Д.) И выходы (только содержимое записанного архивного файла); или 2) напишите истинный единичный тест, который проверяет поведение 'archivingBean', взаимодействуя с отдельными единицами (новые классы, извлеченные из частных методов, называемых' archivingBean.moveDataToArchive'). –