0

在 JUnit 测试中,我想在 Spring DAO 中更改休眠模板。这个 DAO 是

  1. 用 @Transactional 注释,因此它在运行时被包装,并且
  2. 被 Mockitos spy()- 方法监视。因此,DAO 将被该间谍第二次包裹。

所以DAO 现在有两个包装对象:一个来自@Transactional,一个来自间谍。由于不知道首先创建哪些包装器,我无法通过反射在 DAO 中设置休眠模板。

如何在双重包装的 DAO 中设置模板?

[编辑]

一些来源:

/**
* This class gets wrapped by a proxy object because of @Transactional.
*/
@Transactional 
public class MyDao implements SomeDaoInterface { ... }

在测试类中:

public class MyTestClass {
@Autowired 
private MyDao myDao;

@Test
public void myTestMethod() throws Exception {
   final MyDao daoSpy = spy(myDao);   // Dao gets wrapped with second wrapper

   final Field field = MyDao.class.getDeclaredField("template");
   field.setAccessible(true);
   field.set(daoSpy, mySpecialMockedTemplate);  // ERROR: want to inject the template but
                                                // dont know in which wrapper
}
}
4

2 回答 2

2

调用 setter 方法而不是访问该字段。

于 2011-11-04T15:28:13.417 回答
2

看来您的反射代码是错误的。请改用此语句:

field.set(daoSpy, mySpecialMockedTemplate);

但是查看您的测试代码,您似乎正在使用 Spring 来创建MyDao实例。使用反射来设置模板似乎有点奇怪,为什么不在 Spring 中配置呢?甚至使用实际的二传手?或者使该字段受到保护,因此只有单元测试可以访问它。

编辑:关于注入,您可以在测试中创建 DAO 实例specialMockedTemplate并由 Mockito 注入。你可以写这样的东西:

@RunWith(MockitoJUnitRunner.class)
public class MyTestClass {
    @InjectMocks private MyDao dao;

    @Mock SpecialTemplate specialTemplate;

    @Test void dao_should_call_the_template_with_parameter_A_and_B() {
        // given

        // when
        dao.someCall("A", "B");

        // then
        verify(specialTemplate).someCallWith("A", "B");
    }
}

不过有一些警告,如果可能的话,请避免部分嘲笑(使用间谍)。避免嘲笑你不拥有的类型,你应该阅读这篇博客文章为什么这是一个坏主意。

于 2011-11-04T15:53:58.153 回答