Инъекция объектов Mockito Mock с использованием Spring JavaConfig и @Autowired
Я пытаюсь заменить объект @Autowired
на объект Mockito mock. Обычный способ сделать это был с помощью xml с помощью Springockito:
<mockito:mock id="SomeMock" class="com.package.MockInterface" />
В настоящее время я пытаюсь перейти к использованию Spring JavaConfig для выполнения задания. Внезапно выражения Java намного сложнее, чем xml:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration
public class MyTestClass {
@Configuration
static class Config {
@Bean
public MockInterface somethingSpecial() {
return Mockito.mock(MockInterface.class);
}
}
@Autowired MockInterface mockObj;
// test code
}
Я открыл библиотеку под названием Springockito-аннотации, которая позволяет вам сделать следующее:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(loader=SpringockitoContextLoader.class)
public class MyTestClass {
@Autowired @ReplaceWithMock MockInterface mockObj;
// test code
}
Ясно, что все намного красивее:) Единственная проблема заключается в том, что этот загрузчик контекста не позволяет мне использовать @Configuration
и JavaConfig для других beans (если я делаю, Spring жалуется, что нет кандидатов которые соответствуют этим полям с автоподдержкой).
Вы, ребята, знаете, как получить Spring JavaConfig и Springockito-аннотации, чтобы играть хорошо? Кроме того, существует ли еще одна стенограмма для создания mocks?
В качестве приятного бонуса, используя Springckito и xml config, я смог издеваться над конкретными классами, не предоставляя кандидатам автоподготовки для своих зависимостей (если бы они были). Это невозможно без xml?
Ответы
Ответ 1
Отступая от оставшегося без изменений (начиная с этого письма) аннотаций Spingockito и Mockito, у нас есть способ сделать это очень просто:
@RunWith(MockitoJUnitRunner.class)
@ContextConfiguration
public class MyTestClass {
@Mock MockInterface mockObj;
// test code
}
Если вы используете реальный объект, но хотели бы издеваться над ним, например, тестируя сервисный уровень с помощью DAO:
@RunWith(MockitoJUnitRunner.class)
@ContextConfiguration
public class MyTestClass {
@InjectMocks RealService;
@Mock MockDAO mockDAO;
// test code
}
Наконец, это также можно применить к Spring -boot, но используя инициализацию аннотации внутри setUp()
до тех пор, пока не будут поддерживаться несколько классов:
@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = MyMainSpringBootClass.class)
public class MyTestClass {
@InjectMocks RealService;
@Mock MockDAO mockDAO;
@Before
public final void setUp() throws Exception{
MockitoAnnotations.initMocks(this);
}
// test code
}
Ответ 2
Устаревшие и устаревшие!
Пожалуйста, прочитайте также ответ @ethesx,
Springockito is unmaintaned
Старый ответ
Теперь можно сделать mock Spring приложение без XML файла с Springockito-annotations. Это решение работает также с Spring Загрузка.
import static org.mockito.BDDMockito.*;
import org.kubek2k.springockito.annotations.*;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = Application.class,
loader = SpringockitoAnnotatedContextLoader.class)
@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_CLASS)
public class MainControllerTest {
@Autowired
MainController mainController;
@Autowired
@ReplaceWithMock
FooService fooService;
@Test
public void shouldGetBar() {
//given
given(fooService.result("foo")).willReturn("bar");
//when
Bar bar build = fooService.getBar("foo");
//then
assertThat(bar).isNotNull();
}
}
Зависимости: org.kubek2k:springockito-annotations:1.0.9
Ответ 3
Похоже, что SpringockitoContextLoader
extends GenericXmlContextLoader, который описывается как:
Конкретная реализация AbstractGenericContextLoader, которая читает определения bean из ресурсов XML.
Итак, вы ограничены определениями xml bean на данный момент.
Вы можете написать свой собственный загрузчик контекста, взяв соответствующие части из класса SpringockitoContextLoader
. Посмотрите здесь, чтобы начать, возможно, вы можете расширить AnnotationConfigContextLoader например?