Как издеваться над поведением Springockito издевается?
Если я создаю макет в моем весеннем контекстном файле, используя Springockito, как описано здесь, как мне смоделировать его поведение?
Что я пытаюсь сделать:
- ClassA проходит испытания.
- ClassB автоматически подключен в ClassA.
- ClassB издевается над Springockito.
- ClassA нужен ClassB, чтобы сделать что-то в его PostConstruct.
- Мне нужно издеваться над ClassB, чтобы что-то сделать, поскольку он не может и не должен этого делать.
Делать это просто, без использования Springockito (с использованием Mockito прямо вверх), но мне нужно автоматически подключить эти компоненты и использовать Spring в моих тестах. Любая помощь приветствуется.
3 ответа
Я не знаком с Springockito, но он выглядит интересным для некоторых узких случаев - а именно, для интеграционного тестирования с использованием mocking.
В любом случае, похоже, что для простого случая использования вы расширяете AbstractJUnit4SpringContextTests, вы также можете автоматически подключать ClassB в своем тесте, как в ClassA. Затем вы можете определить ожидаемое поведение для ClassB в вашем методе установки.
Но я думаю, что вам нужно настроить некоторое поведение для bean-компонента ClassB, прежде чем вы получите доступ к нему в вашем методе установки. В этом случае вам может понадобиться другой компонент для настройки ClassB на ожидаемое поведение. Таким образом, ваш testContext.xml будет иметь что-то вроде этого:
<bean id="classA" class="com.jarvis.ClassA" depends-on="classBMockSetter" />
<mockito:mock id="classB" class="com.jarvis.ClassB" />
<bean id="classBMockSetter" class="com.jarvis.test.ClassBMockSetter">
<property name="classB" ref="classB" />
</bean>
ClassBMockSetter будет выглядеть примерно так:
public class ClassBMockSetter {
private ClassB classB;
public void setClassB(ClassB classB) {
this.classB = classB;
given(classB.foo()).willReturn(true);
given(classB.bar()).willReturn(42);
}
}
Я думаю, что это сработало бы, но в этот момент не проще ли просто вручную написать свой макет ClassB?
Обратите внимание, что новые Springockito-аннотации помогают достичь той же цели, не связываясь с контекстом xml и дополнительными вспомогательными классами:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(loader = SpringockitoContextLoader.class, locations = "classpath:test-config.xml")
@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_CLASS)
public class MemoAutoTest extends AbstractJUnit4SpringContextTests {
@Autowired
private ClassA classA;
@Autowired @ReplaceWithMock
private ClassB classB;
@Test
public void testClassA() {
// stub B
when(classB.foo()).thenReturn(true);
when(classB.bar()).thenReturn(42);
// test A
}
}
Это приведет к замене ClassB на mock при инициализации основного контекста приложения.
То, что работает для меня, это использование нотации @InjectMocks. (См. https://bitbucket.org/kubek2k/springockito/wiki/Home)
@RunWith (SpringJUnit4ClassRunner.class) @ContextConfiguration (loader = SpringockitoContextLoader.class, местоположения = "classpath:test-config.xml") @DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_CLASSJTexTestTextSTextTextSTextTextSTextText).Text.
@Autowired
private ClassA classA;
@Autowired @InjectMocks
private ClassB classB;
@Test
public void testClassA() {
// stub B
when(classB.foo()).thenReturn(true);
when(classB.bar()).thenReturn(42);
// test A
classA.doSomethingThatInternallyCallClassBFoo();
}
}