gpt4 book ai didi

java - 如何在模拟依赖项时测试事务回滚是否有效?

转载 作者:搜寻专家 更新时间:2023-11-01 03:27:43 26 4
gpt4 key购买 nike

假设我有这个:

@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 Transaction 注释,所以我有一个这样的测试:

@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 不使用接口(interface),我可以使用 CGLIB,但我不想那样做。如果我以编程方式创建 impl,那么它就不会绑定(bind)到事务流中。我还有哪些其他选择?

最佳答案

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

  • 利用 @Profile - 在 Spring 3.1 中,您可以关联 profile每个 bean 的名字。当您启动应用程序上下文时,您提供 Activity 配置文件,并且只有没有任何配置文件关联或提供的配置文件匹配的 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 中 Autowiring otherService 您可以使用 primary="true" 属性或 @Primary 注释定义第二个模拟 bean。 Autowiring 时,Spring 会更喜欢主 bean。

  • 展开事务代理(参见:Is it possible to unproxy a Spring bean?Mocking a property of a CGLIB proxied service not working)以访问 setter。有点 hacky,但对其他人有用

关于java - 如何在模拟依赖项时测试事务回滚是否有效?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9065108/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com