Могу ли я высмеивать вызов метода суперкласса?
Иногда вы хотите протестировать метод класса и хотите выполнить ожидание при вызове метода суперкласса. Я не нашел способ сделать это ожидание в java, используя easymock или jmock (и я думаю, что это невозможно).
Существует (относительное) чистое решение, чтобы создать делегат с логикой метода суперкласса, а затем установить на него ожидания, но я не знаю, почему и когда использовать это решение - любые идеи/примеры?
Спасибо
Ответы
Ответ 1
Хорошо, вы можете, если хотите. Я не знаю, знакомы ли вы с JMockit, идите проверить это. Текущая версия - 0.999.17. Пока что взглянем на нее...
Предположим, что следующая иерархия классов:
public class Bar {
public void bar() {
System.out.println("Bar#bar()");
}
}
public class Foo extends Bar {
public void bar() {
super.bar();
System.out.println("Foo#bar()");
}
}
Затем, используя JMockit в FooTest.java
, вы можете подтвердить, что вы действительно делаете вызов Bar
из Foo
.
@MockClass(realClass = Bar.class)
public static class MockBar {
private boolean barCalled = false;
@Mock
public void bar() {
this.barCalled = true;
System.out.println("mocked bar");
}
}
@Test
public void barShouldCallSuperBar() {
MockBar mockBar = new MockBar();
Mockit.setUpMock(Bar.class, mockBar);
Foo foo = new Foo();
foo.bar();
Assert.assertTrue(mockBar.barCalled);
Mockit.tearDownMocks();
}
Ответ 2
Я не думаю, что высмеиваю супер-вызов - мне кажется, что поведение есть часть поведения самого класса, а не поведение зависимости. Мышление всегда кажется, что это должно быть связано с зависимостями больше, чем что-либо еще.
Есть ли у вас хороший пример того типа звонка, который вы хотите издеваться? Если вы хотите издеваться над таким вызовом, стоит ли рассматривать композицию вместо наследования?
Ответ 3
Развернувшись на @Cem Catikkas, ответьте, используя JMockit 1.22:
@Test
public void barShouldCallSuperBar() {
new MockUp<Bar>() {
@Mock
public void bar() {
barCalled = true;
System.out.println("mocked bar");
}
};
Foo foo = new Foo();
foo.bar();
Assert.assertTrue(mockBar.barCalled);
}
Не требуется статический класс, аннотированный с помощью @MockClass, он заменяется классом MockUp.
Ответ 4
Нет, нет способа издеваться над методами суперкласса с jMock.
Однако существует и быстрое и грязное решение вашей проблемы. Предположим, что у вас есть класс A, а класс B расширяет A. Вы хотите издеваться над методом Aa() на B. Вы можете ввести класс C extends B в свой тестовый код и переопределить метод Ca() (просто вызвать super или вернуть null, id не важно). После этого издевайтесь над C и используйте макет везде, где вы будете использовать B.
Ответ 5
Есть несколько тестов, которые делают именно это (т.е. определяют ожидаемый вызов метода суперкласса) с использованием API ожиданий JMockit, в тестовом наборе анимированных переходов. Например, FadeInTest тестовый пример.
Ответ 6
перехват супервызов слишком мелкозернистый. Не переусердствуйте.