Ложные методы, не вызываемые напрямую в модульном тесте с JMock - PullRequest
0 голосов
/ 03 февраля 2012

У меня есть тестируемый метод.В своем стеке вызовов он вызывает DAO, который использует JDBC для чата с БД.Мне не очень интересно знать, что произойдет на уровне JDBC;У меня уже есть тесты для этого, и они прекрасно работают.

Я пытаюсь смоделировать, используя JMock, слой DAO, поэтому я могу сосредоточиться на деталях этого тестируемого метода.Вот базовое представление о том, что у меня есть.

@Test    
public void myTest()
{
     context.checking(new Expectations() {
          {
               allowing(myDAO).getSet(with(any(Integer.class)));
               will(returnValue(new HashSet<String>()));
          }
     });

    // Used only to show the mock is working but not really part of this test.
    // These asserts pass.
    Set<String> temp = myDAO.getSet(Integer.valueOf(12));
    Assert.assertNotNull(temp);
    Assert.assertTrue(temp.isEmpty());

    MyTestObject underTest = new MyTestObject();
    // Deep in this call MyDAO is initialized and getSet() is called.
    // The mock is failing to return the Set as desired. getSet() is run as 
    // normal and throws a NPE since JDBC is not (intentionally) setup. I want 
    // getSet() to just return an empty set at this layer.
    underTest.thisTestMethod();
    ...
    // Other assertions that would be helpful for this test if mocking 
    // was working.
}

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

Мысли и спасибо.

1 Ответ

0 голосов
/ 07 февраля 2012

Из фрагмента я предполагаю, что MyTestObject использует отражение, или статический метод или поле, чтобы получить DAO, поскольку у него нет параметров конструктора. JMock не выполняет замену объектов по типу (и в любой момент будет куча людей, рекомендующих другие фреймворки, которые это делают).

Это специально. Цель JMock состоит в том, чтобы выделить слабые стороны объектного дизайна, требуя чистых зависимостей и сфокусированного поведения. Я обнаружил, что утечка доступа к DAO / JDBC в доменных объектах в конечном итоге приводит к неприятностям. Это означает, что доменные объекты имеют секретные зависимости, которые затрудняют их понимание и изменение. Я предпочитаю сделать эти отношения явными в коде.

Итак, вы должны каким-то образом вставить макет объекта в целевой код. Если вы не можете или не хотите этого делать, вам придется использовать другой фреймворк.

P.S. Одна точка стиля, вы можете немного упростить этот тест:

context.checking(new Expectations() {{
  allowing(myDAO).getSet(12); will(returnValue(new HashSet<String>()));
}});

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

...