gpt4 book ai didi

java - JMockit Deencapsulation setField 不持久

转载 作者:行者123 更新时间:2023-11-29 04:28:16 30 4
gpt4 key购买 nike

我正在我的 JPA 层和数据库之间编写集成测试,以检查我编写的 SQL 是否正确。真正的数据库是 Oracle,不幸的是,由于我无法控制的原因,我的测试数据库必须是 Derby,所以自然会有一些差异。例如,我的 JPA 类具有以下 SQL 字符串常量

private static final String QUERY = "Select * from Users where regexp_like(user_code, '^SS(B)?N')";

因为 Derby 不支持 regexp_like 我正在使用 JMockits Deencapsulation.setField 动态更改 SQL。例如。

@Test
public void testMyDaoFind() {
new Expectations() {
{
Deencapsulation.setField(MyClass.class, "QUERY", "Select * from Users");
}
};

dao.findUsers();
}

现在忽略这不是一个好的测试这一事实,因为它没有测试将在真实数据库上运行的实际查询(这纯粹是为了满足我对正在发生的事情的好奇心),我得到了来自 Eclipselink/Derby 的 SQL 异常错误提示 regexp_like 未被识别为函数或过程。

如果我在 DAO 中尝试获取结果列表的行上放置一个断点,我可以从一个新 watch 中看到

  1. JMockit 已正确替换查询

  2. getResultList() 返回我期望看到的数据

但是,如果我让测试一直运行,那么我会得到上述异常?!

最佳答案

Java 中的字符串处理方式与您想象的不同。 Java 源代码编译器用存储字符串的固定“地址”(在类的常量池中)替换从保存字符串文字的字段读取;该字段在运行时不再读取。因此,即使 JMockit 替换了字段中存储的字符串引用,也没有任何区别,因为使用该字段的客户端代码看不到该引用。

(顺便说一句,为什么测试将对 Deencapsulatin.setField 的调用放在期望 block 中?这样的 block 仅用于记录期望...)

归根结底,您无法实现您的目标。相反,要么使用 Oracle 数据库进行集成测试,要么使所有 SQL 代码可移植,避免 RDBMS 特定的函数,例如 regexp_like

关于java - JMockit Deencapsulation setField 不持久,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45141157/

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