- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我正在努力为我的 DAO 层设置一些单元测试用例,以确保它以我需要的方式响应,为此,我需要对我的 jOOQ 代码进行单元测试。我此时正在运行 jOOQ 3.6.1,并尝试使用 JDBC 模拟,如 jOOQ documentation 中的此链接中所述。 .
我的单元测试环境正在利用 jUnit 4.12 和mockito。
不幸的是,虽然这对于 SELECT 查询非常有效,但我很难弄清楚我在 UPDATE 查询中做错了什么。在非 jUnit 单元测试中,我知道该函数本身正在工作(它也非常基本,因此并不令人震惊),但我也希望能够对这段代码进行一些自动化单元测试。
我的单元测试按以下方式设置:
public class UserDAOTest {
private static UserDAO userDAO;
private static Logger LOG = Logger.getLogger(UserDAOTest.class.getName());
private class MyMockDataProvider implements MockDataProvider {
@Override
public MockResult[] execute ( MockExecuteContext ctx ) throws SQLException {
DSLContext create = DSL.using(SQLDialect.MYSQL);
MockResult[] result = new MockResult[1];
String sql = ctx.sql();
if ( sql.toUpperCase().startsWith("UPDATE") ) {
Result<UserRecord> userRecordResult = create.newResult(USER);
userRecordResult.add(create.newRecord(USER));
userRecordResult.get(0).setValue(USER.ID, 1000);
userRecordResult.get(0).setValue(USER.USERNAME, "BrumbyUpdateTest");
userRecordResult.get(0).setValue(USER.CREATED_ON, new Timestamp((new Date()).getTime()));
userRecordResult.get(0).setValue(USER.UPDATED_ON, new Timestamp((new Date()).getTime()));
userRecordResult.get(0).setValue(USER.USER_TYPE, "Poster");
userRecordResult.get(0).setValue(USER.PASSWORD, BCrypt.hashpw("12341234", BCrypt.gensalt()));
result[0] = new MockResult(1, userRecordResult);
}
LOG.info("[execute] :: MockResult.rows=" + result[0].rows);
LOG.info("[execute] :: MockResult.data=" + result[0].data);
LOG.info("[execute] :: result=" + result.toString());
return result;
}
@Before
public void setupTest() {
DataSourceFactory mockDataSource = mock(DataSourceFactory.class);
ManagedDataSource ds = mock(ManagedDataSource.class);
when(mockDataSource.build(any(), any())).thenReturn(ds);
Environment environment = mock(Environment.class);
try {
when(ds.getConnection()).thenReturn(connection);
} catch (SQLException sqle) {
LOG.warning("[setupTest] :: sqle=" + sqle.getMessage());
}
userDAO = new UserDAO(mockDataSource.build(environment.metrics(), "ds"));
}
@Test
public void testUpdatePassword() {
boolean out = userDAO.updatePassword(1000, "12341234");
assertThat(out).isEqualTo(true);
}
}
我阅读jOOQ JavaDocs的理解是这应该最终使用 MyMockDataProvider 并在使用我创建的结果执行 UPDATE 查询时做出响应。我相信我正在创建一个新的 MockResult,其行数为 1,并且其中指定了 User 对象。当我查看放入其中的日志语句时,这就是正在发生的事情。
Jul 23, 2015 9:23:04 AM com.mycompany.dao.UserDAOTest$MyMockDataProvider execute
INFO: [execute] :: MockResult.rows=1
Jul 23, 2015 9:23:04 AM com.mycompany.dao.UserDAOTest$MyMockDataProvider execute
INFO: [execute] :: MockResult.data={Expected Data Based on MyMockProvider}
但是当我执行单元测试时,UserDAO 对象将来自 jOOQ 的响应视为记录计数 0。
Jul 23, 2015 9:23:04 AM com.mycompany.dao.UserDAO updatePassword
WARNING: [updatePassword] :: count=0
我尝试测试的代码如下:
public class UserDAO {
public boolean updatePassword ( Integer id, String newPassword ) {
try ( Connection conn = ds.getConnection() ) {
DSLContext updatePassword = DSL.using(conn, SQLDialect.MYSQL);
int count = updatePassword.update(USER)
.set(USER.PASSWORD, BCrypt.hashpw(newPassword, BCrypt.gensalt()))
.where(USER.ID.eq(id))
.execute();
LOG.warning("[updatePassword] :: count=" + count);
if ( count != 1 ) return false;
return true;
} catch ( SQLException sqle ) {
LOG.warning("[updatePassword] :: sqle=" + sqle.getMessage());
return false;
}
}
}
我是否错误地使用了 MockResult 对象?也许我有误解,但我相信更新会返回受影响的记录数,根据我返回的 MockResult,该记录数应该为 1。但是 UserDAO 对象返回 0,因此我的测试失败了。
预先感谢您的任何帮助,或者我可以解决此问题的方向。
最佳答案
我不知道我这样做是否正确,因为我正在回答自己的问题,但我认为我是。我花了两天的时间研究这个问题并单步执行 jOOQ 代码以了解问题所在。事实证明,问题在于我在测试的这一行中的 MockResult 对象中提供的数据:
result[0] = new MockResult(1, userRecordResult);
由于我在更新后没有获取数据,所以我不应该包含它。基本上,我可以删除构建 userRecordResult 对象的所有代码行,而只需设置 MockResult 对象,如下所示:
result[0] = new MockResult(1, null);
我相信这对我来说有一个结果,但没有数据。由于现在没有返回数据,MockStatement.execute0()函数现在返回 false 而不是 true。然后当在AbtractQuery.execute()时函数中,第 410 - 413 行的 if block 被触发,结果计数被设置为该值。
if (!stmt.execute()) {
result = stmt.getUpdateCount();
ctx.rows(result);
}
之前,当我在 MockResult 对象中拥有数据时,MockStatement.execute0() 函数返回 true,因此上面的 if block 从未执行,并且 result
int 从创建时起从未更改为零。但对于空数据,会触发 result = stmt.getUpdateCount();
行并设置我的值。
关于java - 在 jUnit 测试的 UPDATE 语句中使用 jOOQs MockResult 类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31591608/
我已经从 MySQL 表生成了 java 模型文件。但是现在我们正在切换到 PostgreSQL,我需要一切才能在那里工作。所以我为 PostgreSQL 配置创建了一个新的 jooq.propert
在 mysql 数据库中,我有一个字段名称 date 类型 date 该字段的值如下2019-11-05 如何在jooq中查询上面提到的日期 我试着跟随 java.util.Date date = S
我正在调查一个问题,我们看到与 jooq 相关的奇怪异常试图填充生成的 Record 类,它在其中获取数据类型错误,因为它使用 java.sql.ResultSet::getXXX(int)(基于列索
我一直在寻找一种在 jOOQ 中实现以下查询的方法,但找不到任何东西。 SELECT * FROM tableName WHERE 'this is a string' LIKE CONCAT(
我一直在寻找一种在 jOOQ 中实现以下查询的方法,但找不到任何东西。 SELECT * FROM tableName WHERE 'this is a string' LIKE CONCAT(
我有一个使用gradle-jooq-plugin-3.0.1、jooq-3.11.2 和 Spring Boot 1 的项目。当我尝试生成 JOOQ 文件时我收到以下错误消息: > Task :gen
我刚刚尝试将我的项目升级到 Java 15,现在出现以下错误: both interface org.jooq.Record in org.jooq and class java.lang.Rec
我很好奇 jOOQ 是否可以与 Quarkus 一起工作,所以我创建了一个 Gradle 项目。我收到此构建错误: Caused by: io.quarkus.creator.AppCreatorEx
来自 fetchNext(int number) 的文档 -“在获取最后一条记录后,这将方便地关闭游标。” 假设number=100,一共有1000条记录。它会在获取第 100 条记录后关闭游标,还是
在我们的项目中,概念是在配置文件中定义的。举个例子: ... ... 虽然这与 SQL 没有太大关系,但这个配置文件恰好可以映射到 S
我在我的 java gradle 项目中找到一个有效的 JOOQ 插件或其配置为最新的 JOOQ 库时遇到问题。 我找到了以下插件: https://github.com/jOOQ/jOOQ/tree
我得到了一个使用 gradle (v2.1.0) 和 jooq (v3.8.1) 生成类文件的 Ratpack 应用程序。 这是我的 build.gradle 文件: buildscript {
我有一个界面 public interface HistoryDao, H extends UpdatableRecord> extends TableDao{ default void sa
我正在使用 jOOQ 生成针对 Athena(又名 PrestoDB/Trino)运行的查询 为此,我使用了 SQLDialects.DEFAULT,它之所以有效,是因为我使用了非常基本的查询功能。
如何在jooq的查询中绑定(bind)一个数组作为参数? 这是我添加名为“someIds”的命名参数的地方 Query query = selectJoinStep.where(field("
我有一个多模块 maven 项目,我正在实现一个 ant 任务以直接从 jpa 生成 jooq 类 实体。 这些是我引用的教程: Code generation with Ant Code gener
我想在 JOOQ 中实现一个基本的 time_bucket 语句。 如果我在控制台中运行此语句,它运行得非常好: SELECT time_bucket('5 minutes', time) as t,
我关于在 jooq dsl 中编写查询的问题。 我在 Oracle 数据库中存储了一些客户端属性列表。 表结构如下: CLIENT_ATTRIBUTE_DICT (ID、CODE、DEFAULT_VA
我很惊讶地发现 JOOQ(从 3.16 开始)将时间戳绑定(bind)到 LocalDateTime。在我看来,时间戳最自然地映射到一个 Instant,它是一个 Unix 纪元时间戳。 那么我们怎样
你好,我正在方法中执行此操作 public void update(Table table, String tableName){ ArrayList firstRowInDslFormat
我是一名优秀的程序员,十分优秀!