Как создать издевательский (от 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);
    }
}

Spring-ReInject предназначен для замены бобов на макеты.

Другие вопросы по тегам