Обычные методы инициализации bean-компонентов, такие как SpringJUnit4ClassRunner
или MockitoAnnotations.initMocks(this);
, обрабатывающие только один тип инъекций за раз. Либо конструктор, либо автоматическая проводная инъекция.
@RunWith(SpringJUnit4ClassRunner.class)
означает, что открытый класс SpringJUnit4ClassRunner расширяет BlockJUnit4ClassRunner. SpringJUnit4ClassRunner - это пользовательское расширение JUnit. Он инициализирует макет аннотированных bean-компонентов @MockeBean и @bean во время начального запуска теста. Также запускается и инъекция bean-компонента.
MockitoAnnotations.initMocks(this)
метод должен вызываться для инициализации аннотированных полей. В приведенном выше примере initMocks () вызывается в методе @Before (JUnit4) базового класса теста. Для JUnit3 initMocks () может перейти к методу setup () базового класса.
Чтобы в приведенном выше вопросе вы использовали SpringJUnit4ClassRunner и MockitoAnnotations.initMocks (this);он создаст две фиктивные ссылки на bean-компоненты, для которых вы всегда используете @Mock
. Также в приведенном выше потоке кода.
1. В начале выполнения SpringJUnit4ClassRunner
он создаст ссылку на bean-компонент для аннотированных атрибутов @Mock и @MockBean. После того, как он создаст внедренный bean-компонент в это время, происходит только конструкторинъекция
2. Выполните @Before и запустите MockitoAnnotations.initMocks(this);
, чтобы создать еще одну фиктивную ссылку для аннотированных атрибутов @Mock и заменить только прямые ссылки. и в этот момент запускается автоматический проводной впрыск.
После запуска
MockitoAnnotations.initMocks(this);
вы увидите, что бобы allk инициализированы и правильно введены. Но бины, которые вводятся через конструктор, эти бины не являются правильной ссылкой, они ссылаются на старую ссылку на бин, созданную SpringJUnit4ClassRunner.
Если вы хотите получить конструктор и автоматическую проводную инъекцию для одного бина, выдолжен использовать ручной бин, вводимый для конструктора. Вы можете сослаться здесь
Решение:
@RunWith(SpringJUnit4ClassRunner.class)
Class TestClass{
@MockBean
A mockA
@MockBean
B mockB
@MockBean
C mockC
@Autowired
D mockD
@Before
public void setUp() {
mockD = new D(mockA,mockB);
MockitoAnnotations.initMocks(this);
when(mockA.getValue()).then("StringValA");
when(mockB.getValue()).then("StringValB");
when(mockC.getValue()).then("StringValC");
}
@Test
public void testMethod(){
mock.getAllValues();// It will call all injested bean method we are mocked in @before
}
}