如何创建一个模拟(由jmockit)的springbean?

如何创建一个模拟(由jmockit)的springbean?,spring,jmockit,Spring,Jmockit,我是jmockit新手,希望在基于Java的Spring应用程序配置中模拟bean。我认为(最好是希望)会是这样的: @Configuration public class MyApplicationConfig { @Bean // this bean should be a mock SomeService getSomeService() { return new MockUp<SomeService>() {@Mock String someMethod()

我是jmockit新手,希望在基于Java的Spring应用程序配置中模拟bean。我认为(最好是希望)会是这样的:

@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) {
    ....
  }
}
@配置
公共类MyApplicationConfig{
@Bean//这个Bean应该是模拟的
SomeService getSomeService(){
返回新的模型(){@Mock String someMethod(){return”“;}}}.getMockInstance();
}
@Bean//依赖于模拟服务Bean的其他Bean
MyApplication getMyApplication(SomeService SomeService){
....
}
}
但不幸的是,这在“应用模型的位置无效”的情况下失败了

我想知道我是否能在Spring配置类中生成jmockit mock。我需要这个bean,因为它被其他bean引用,如果我不将mock作为springbean提供,那么整个Spring上下文初始化都会失败


感谢您的帮助。

旨在用mock替换bean。

只需使用常规的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;
    }
}




有趣的是,在我的例子中,a有一个专用的Spring测试配置,可以就地生成模拟(无需重新注入)。如果可能的话,我更喜欢这种尝试,但如果不是这样,我可能会更深入地查看您的库。谢谢你,现在是+1!感谢-将研究此方法。不幸的是,如果在Spring上下文初始化期间需要模拟实例,则此方法不起作用。问题是:如何生成一个jmockit模拟实例,并在测试之外定义行为?顺便说一句,jmockit确实是一个很棒的框架,但是在您的应用程序中应该提到仅限内部测试的限制。目前看来,jmockit确实可以做任何事情。但我第一次尝试使用它时失败了:-(别误会我的意思-使用它有很多很好的理由,我不想批评)在测试中不使用真正的spring配置可能有几个原因。例如,因为您不需要为bean提供安装属性,您将在测试之后模拟这些bean,或者您不想在测试期间激活应用程序的特殊部分(例如,作业排程)。看不到执行(或不执行)的原因一般来说,为自己做的事情并不意味着其他任何人也必须这么想。顺便问一下,为什么模拟只对(单元)测试有用?您也可以将软件部署到(测试)环境中,在那里您需要模拟某些部分(阶段,…)。我不知道JUnit,但上面的代码对TestNG不起作用。有一次,我得到了
null two
,这意味着两个模拟方法中的一个有效,另一个无效。但更重要的是,Spring尝试首先构建上下文,这意味着必须满足
SomeService
的依赖关系。对我来说,这意味着我必须用Mockito执行我的Spring MVC测试,因为JMockit不够。
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);
    }
}