Как создать издевательский (от jmockit) боб весны?
Я новичок в jmockit и хотел бы смоделировать bean-компонент внутри моей Spring Application Configuration приложения на основе Java. Я думал (лучше надеяться), что это пойдет так:
@Configuration
public class MyApplicationConfig {
@Bean // this bean should be a mock
SomeService getSomeService() {
return new MockUp<SomeService>() {@Mock String someMethod() { return ""; }}.getMockInstance();
}
@Bean // some other bean that depends on the mocked service bean
MyApplication getMyApplication(SomeService someService) {
....
}
}
Но, к сожалению, это не с "Недопустимым местом для применения макета".
Интересно, могу ли я вообще генерировать макеты jmockit внутри классов Spring Configuration. Мне нужен bean-компонент, потому что на него ссылаются другие bean-компоненты, и инициализация всего Spring Context завершается неудачно, если я не предоставляю макет как bean-компонент Spring.
Спасибо за любую помощь.
2 ответа
Просто используйте вашу обычную конфигурацию Spring. В тестовом классе объявите тип, с которым нужно поиграться @Capturing
, Он будет издеваться над тем классом реализации, который использовал Spring.
Изменить: добавлен полный пример кода ниже.
import javax.inject.*;
public final class MyApplication {
private final String name;
@Inject private SomeService someService;
public MyApplication(String name) { this.name = name; }
public String doSomething() {
String something = someService.doSomething();
return name + ' ' + something;
}
}
public final class SomeService {
public String getName() { return null; }
public String doSomething() { throw new RuntimeException(); }
}
import org.springframework.context.annotation.*;
@Configuration
public class MyRealApplicationConfig {
@Bean
SomeService getSomeService() { return new SomeService(); }
@Bean
MyApplication getMyApplication(SomeService someService) {
String someName = someService.getName();
return new MyApplication(someName);
}
}
import javax.inject.*;
import org.junit.*;
import org.junit.runner.*;
import static org.junit.Assert.*;
import mockit.*;
import org.springframework.test.context.*;
import org.springframework.test.context.junit4.*;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = MyRealApplicationConfig.class)
public final class MyApplicationSpringTest {
@Inject MyApplication myApplication;
@Mocked SomeService mockService;
@BeforeClass // runs before Spring configuration
public static void setUpMocksForSpringConfiguration() {
new MockUp<SomeService>() {
@Mock String getName() { return "one"; }
};
}
@Test
public void doSomethingUsingMockedService() {
new Expectations() {{ mockService.doSomething(); result = "two"; }};
String result = myApplication.doSomething();
assertEquals("one two", result);
}
}
import org.junit.*;
import static org.junit.Assert.*;
import mockit.*;
// A simpler version of the test; no Spring.
public final class MyApplicationTest {
@Tested MyApplication myApplication;
@Injectable String name = "one";
@Injectable SomeService mockService;
@Test
public void doSomethingUsingMockedService() {
new Expectations() {{ mockService.doSomething(); result = "two"; }};
String result = myApplication.doSomething();
assertEquals("one two", result);
}
}