0

我正在尝试使用 Mockito 框架模拟一个本地对象,该对象是从 spring 应用程序上下文创建的;但是每次我运行应用程序时,它都无法用模拟对象替换原始对象。

这是原始类的代码尖峰:

public void executeMyJob(){
    ApplicationContext springContext = ApplicationContextUtil.getApplicationContext();

    MusicEAO music= (MusicEAO) springContext.getBean("MusicEAO");
    List<Brand> dataList =music.getAll();

    ......
}  

我想模拟,MusicEAO所以当getAll()调用该方法时,它将使用模拟对象。

下面是我的测试类代码片段:

@Mock
MusicEAO musicEAO;
when(musicEAO.findAll()).thenReturn(myDefinedList);

我该如何解决这个问题?

4

2 回答 2

3

很难从您发布的 cod 中分辨出来,但问题可能是您在测试中模拟 MusicEAO,但您正在执行的代码使用 Spring ApplicationContext 来获取对 MusicEAO bean 的引用。

您的原始类不应该使用MusicEAO music= (MusicEAO) springContext.getBean("MusicEAO");,而是让 Spring@Autowired通过构造函数或 setter 方法(或其他依赖注入方法)注入 bean。然后您的测试将能够轻松地注入模拟版本。

 class MyJobClass {

   MusicEAO music;

   @Autowired
   public MyJobClass(MusicEAO musicEao) {
      this.music = musicEao;
   }

   public void executeMyJob(){

       List<Brand> dataList =music.getAll();

       ......
   } 
}

当你说

每次我运行应用程序时,它都无法用模拟对象替换原始对象

你不应该运行应用程序来运行这个类的单元测试——你是在问如何将模拟注入到正在运行的应用程序中?

.

于 2012-10-29T14:54:32.310 回答
0

这种方式行不通。在您当前的代码中:

  • 以下实例是您的测试中的实例: @Mock MusicEAO musicEAO;

  • 但是在您的生产代码中,您使用 Spring 来获取 Music 实例: MusicEAO music= (MusicEAO) springContext.getBean("MusicEAO");

您似乎没有对 spring 说您希望 Music mock 受到MusicEAObean 名称的影响。

如果您正在进行单元测试,我会建议您避免弄乱 Spring,如果这是一个集成测试,那么您必须找到一种方法来创建模拟并将其传递给 Spring。

例如,您可以在 Spring 上下文中创建模拟,在您的测试中自动装配它。

此外,我不建议在这种情况下使用静态调用来获取 Spring 上下文以最终获得对Music对象的控制。它让我认为 Spring 是一个注册表,但事实并非如此。Spring是一个容器。相反,您应该尝试重构代码,使Musicbean 连接(@Autowired、setter 等)在ExecutionJob.

然后使用 JUnit 和 Mockito 编写单元测试会更容易,并带有 和 之类的@Mock注释@InjectMocks

希望有帮助。

于 2012-10-29T15:07:55.023 回答