JMockit Troubles (только начало) - PullRequest
       4

JMockit Troubles (только начало)

1 голос
/ 09 сентября 2010

Так что у меня есть своего рода запутанная проблема, я опишу ее с помощью аналогичных примеров вместо того, чтобы копировать TONS кода. Проблема заключается в том, что я не очень хорошо знаю, как правильно использовать JMockit, смею сказать правильно.

У меня есть интерфейс:

public interface IRsrcResolver {
 RsrcSet getForQuery(Query, RsrcContext, int);
}

Реальная реализация этого есть - она ​​довольно интенсивная.Так что я сделал поддельную версию, которая просто возвращает ноль.Затем я хочу установить [нестрогое] ожидание, которое будет возвращать правильные значения.Это меняет тест на тест.

В коде:

public class MockRsrcResolver implements IRsrcResolver { 
  RsrcSet getForQuery(Query, RsrcContext, int) { return null; } 
}

в классе Test я реализую его и затем хочу установить ожидания (StateEngine использует RsrcResolver)

    public class StateEngineTest {
      @Mocked
      public IRsrcResolver rsrcResolver;
      @Mocked
      public RsrcSet rsrcSet;

      @Mocked
      private StateEngine stateEngine;


      public void setUp () throws Exception {
        stateEngine = new StateEngine ();
        rsrcResolver = new MockRsrcResolver ();
        rsrcSet = new RsrcSet ();

        new NonStrictExpectations () {
          {
            rsrcResolver.getForQuery((Query) any, (RsrcContext)any, anyInt);
            result = rsrcSet;
          }
        }
      }


    @Test
    public void testSetState () {
      /*... does something that calls getForQuery (...) on an IRsrcResolver ...*/
      stateTest.doSomething ();
      /* ... assert assert assert ... */
    }  
  }

IndoSomething что-то вроде:

  IRsrcResolver m_rsrcResolver = new RsrcResolver ()
  RsrcSet m_rsrcSet = m_rsrcResolver.getQuery (query, rsrcCtx, 4);
  m_rsrcSet.doSomethingElse ();

m_rsrcSet получает нулевое значение, и отладка показывает, что он обращается к нулевому MockRsrcResolver вместо использования ожидания ... Я неправильно сделал это таким образом?Спасибо за любой совет, который вы можете получить!

1 Ответ

1 голос
/ 09 сентября 2010

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

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

Неправильное использование поддельных переменных ожидания. rsrcResolver, rsrcSet и stateEngine не должны задаваться значения. Они на самом деле являются заполнителями для надуманных экземпляров, которые магически генерирует JMockit.

Решение 1

Вот как я бы смоделировал этот метод, если бы RsrcSet не нужно было высмеивать:

final RsrcSet queryResult = new RsrcSet();
// (insert initialization of queryResult here)

new NonStrictExpectations () {
  RsrcResolver rsrcResolver;
  {
    rsrcResolver.getForQuery((Query) any, (RsrcContext)any, anyInt);
    result = queryResult
  }
}

Обратите внимание, что я объявляю переменные "фиктивного заполнителя" как член ожидания, а не как член тестового класса. Может быть, последний тоже работает, я не знаю (есть много способов добиться того же результата с JMockit). Но важно то, что я не переназначаю эти переменные.

Вышеуказанное ожидание означает: «перехватывать все вызовы метода RsrcResolver#getForQuery и вместо этого возвращать экземпляр queryResult». На самом деле я не уверен в точном поведении, когда использую нестрогие ожидания (в основном я использую строгие ожидания). Возможно, это означает: «перехватывать вызовы всех методов RsrcResolver, ничего не делая и возвращая значения по умолчанию. Но для особого случая метода RsrcResolver#getForQuery верните экземпляр queryResult

Решение 2

Вот как я бы смоделировал этот метод, если RsrcSet#doSomethingElse тоже должен быть высмеян:

new NonStrictExpectations () {
  RsrcResolver rsrcResolver;
  RsrcSet rsrcSet;
  {
    rsrcResolver.getForQuery((Query) any, (RsrcContext)any, anyInt);
    result = rsrcSet;
    rsrcSet.doSomethingElse();
  }
}

Вышеуказанное ожидание означает: «перехватывать все вызовы метода RsrcResolver#getForQuery и возвращать вместо него макетированный RsrcSet экземпляр. Этот макетированный экземпляр ничего не будет делать при вызове". Конечно, если doSomethingElse нужно вернуть значение, вы можете использовать инструкцию result =.

...