Как издеваться над поведением моков Springockito?

Если я создаю макет в своем файле контекста Spring с помощью Springockito, как описано здесь, как мне издеваться над каким-то поведением?

Что я пытаюсь сделать:

  1. ClassA проходит испытания.
  2. ClassB автоматически подключается к ClassA.
  3. ClassB издевается над Springockito.
  4. ClassA нуждается в ClassB, чтобы что-то делать в своем PostConstruct.
  5. Мне нужно издеваться над ClassB, чтобы что-то сделать, поскольку он не может и не должен этого делать.

Это просто сделать без использования Springockito (используя Mockito прямо), но мне нужно автоматически подключить эти bean-компоненты и использовать Spring в моих тестах. Любая помощь приветствуется.


person J. Lin    schedule 21.06.2012    source источник


Ответы (3)


Я не знаком со Springockito, но он выглядит интересным для некоторых узких случаев, а именно для интеграционного тестирования с макетом.

В любом случае, похоже, что для простого варианта использования вы расширяете 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?

person jhericks    schedule 21.06.2012
comment
Спасибо, это именно то, что я искал. Когда вы говорите ручной код макета, где будет жить код, поскольку он должен быть, когда ClassA создается в ClassATest и до того, как будет вызван метод пост-конструкции. - person J. Lin; 21.06.2012

Обратите внимание, что новые аннотации 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 будет заменен имитацией при инициализации основного контекста приложения.

person Vadzim    schedule 21.10.2013
comment
Не могли бы вы поделиться test-config.xml? - person Ika; 03.12.2014

У меня сработало использование нотации @InjectMocks. (См. https://bitbucket.org/kubek2k/springockito/wiki/Home)

@RunWith (SpringJUnit4ClassRunner.class) @ContextConfiguration (loader = SpringockitoContextLoader.class, location = "classpath: test-config.xml") @DirtiesContext (classMode = DirtiesContext.ClassMode.AFTER_CLASS) открытый класс MemoAJutoTestExtends

@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();
}

}

person Ika    schedule 03.12.2014