Java 如何在模拟依赖项时测试事务回滚是否有效?
假设我有这个:Java 如何在模拟依赖项时测试事务回滚是否有效?,java,hibernate,spring,testing,transactions,Java,Hibernate,Spring,Testing,Transactions,假设我有这个: @Transactional(rollbackFor = NotificationException.class) public interface PersonManagerService { public void addPerson(Person person); } 以及一项实施: public class PersonManagerServiceImpl implements PersonManagerService { public OtherService
@Transactional(rollbackFor = NotificationException.class)
public interface PersonManagerService {
public void addPerson(Person person);
}
以及一项实施:
public class PersonManagerServiceImpl implements PersonManagerService {
public OtherService otherService;
public void addPerson(Person person) {
// stuff
}
// getter and setter for otherService
}
在addPerson方法仍然命中数据库的情况下,如何模拟otherService依赖关系
我的场景是,我想测试一个特定的异常是否会导致正在添加的人员的保存回滚。这个异常来自OtherService类,我不想称之为的真实版本。我目前正在使用Spring事务注释,因此我有一个如下测试:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {various locations})
public class Test() {
@Autowired
PersonManagerService service;
@Test
public void test() {
// how to call setOtherService so it can be a mock?
}
如果我尝试强制转换自动连线bean,我会得到一个IllegalArgumentException,因为它是一个代理。如果我让Impl不使用接口,我可以使用CGLIB,但我不想这样做。如果我以编程方式创建impl,那么它就不会绑定到事务流中。我还有什么其他选择?您可以通过各种方式解决此计划(从最佳到最差):
- 利用
s——在Spring 3.1中,您可以将名称与每个bean关联起来。当您启动应用程序上下文时,您提供了活动的概要文件,并且只有没有任何关联概要文件或与提供的概要文件匹配的bean才会被实例化。这是一个非常强大的机制@Profile
@Profile("prd") public class PersonManagerServiceImpl implements PersonManagerService //... @Profile("test") public class PersonManagerServiceMock implements PersonManagerService //... @ContextConfiguration @ActiveProfiles(value = "test") public class Test {
- 使用
或primary
-如果您在@primary
中自动连接PersonManagerServiceImpl
,则可以使用其他服务
属性或primary=“true”
注释定义第二个模拟bean。Spring在自动布线时更喜欢主bean@primary
- 展开事务代理(请参阅:和)以访问setter。有点老套,但对其他人有用