Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/400.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/hibernate/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何在模拟依赖项时测试事务回滚是否有效?_Java_Hibernate_Spring_Testing_Transactions - Fatal编程技术网

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,那么它就不会绑定到事务流中。我还有什么其他选择?

您可以通过各种方式解决此计划(从最佳到最差):

  • 利用
    @Profile
    s
    ——在Spring 3.1中,您可以将名称与每个bean关联起来。当您启动应用程序上下文时,您提供了活动的概要文件,并且只有没有任何关联概要文件或与提供的概要文件匹配的bean才会被实例化。这是一个非常强大的机制

    @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”
    属性或
    @primary
    注释定义第二个模拟bean。Spring在自动布线时更喜欢主bean

  • 展开事务代理(请参阅:和)以访问setter。有点老套,但对其他人有用


这是非常好的信息,谢谢!我知道AopUtils,但不知道如何使用它返回impl,但您在链接中的回答告诉了我如何使用它。我们将很快迁移到3.1,并计划重新修改一些配置,因此希望这将是一个很好的时机。