简体   繁体   English

JOOQ MockDataProvider - 如何根据某些条件返回不同的模拟?

[英]JOOQ MockDataProvider - how to return different mocks depending on some conditions?

Recenty I was implementing a unit test using JOOQ MockDataProvider.最近我正在使用 JOOQ MockDataProvider 实现单元测试。 When I wanted to use my mock provider in DAO with many selects I had to use many if-else statements.当我想在 DAO 中使用具有许多选择的模拟提供程序时,我不得不使用许多 if-else 语句。

According to: http://www.jooq.org/doc/latest/manual/tools/jdbc-mocking , I just need to check if my SQL starts with some query.根据: http : //www.jooq.org/doc/latest/manual/tools/jdbc-mocking ,我只需要检查我的 SQL 是否以某个查询开头。 And my SQLs used in DAO could start with 3 different ways, so I used pretty complex if-else construct.我在 DAO 中使用的 SQL 可以从 3 种不同的方式开始,所以我使用了非常复杂的 if-else 结构。

Second thing - I wanted my MockDataProvider to return some mock result only when SQL is executed for the first time, and then not to return any results - in DAO iterated in loop 5 times, and each time my DAO should check something in database.第二件事 - 我希望我的 MockDataProvider 仅在第一次执行 SQL 时返回一些模拟结果,然后不返回任何结果 - 在 DAO 中循环迭代 5 次,并且每次我的 DAO 都应该检查数据库中的某些内容。 I had no idea how to mock such behaviour, so I used simple counter - but it looks awful, and I want it to be implemented in a good way.我不知道如何模拟这种行为,所以我使用了简单的计数器 - 但它看起来很糟糕,我希望它以一种好的方式实现。 Here is my code:这是我的代码:

public class SomeProvider implements MockDataProvider {

private static final String STATEMENT_NOT_SUPPORTED_ = "Statement not supported: ";
private static final String SELECT_META = "select \"myschema\".\"meta\".";
private static final String SELECT_CLIENT = "select \"myschema\".\"client\".";
private static final String SELECT_KEY = "select \"myschema\".\"key\".";
private static final String TEST_SECRET_KEY = "some key";
private static final String KEY = "40sld";
private static final String DROP = "DROP";
private static final String SOME_URL = "something";
private static final String MONKEY = "monkey";
private static final int FIRST_ITERARION_COUNTER_VALUE = 0;
private final Long keyId;
int counter = 0;

public SomeProvider(Long keyId) {
    this.keyId = keyId;
}

@Override
public MockResult[] execute(MockExecuteContext ctx) throws SQLException {

    DSLContext create = DSL.using(SQLDialect.POSTGRES);
    MockResult[] mock = new MockResult[3];
    String sql = ctx.sql();
    if (sql.toUpperCase().startsWith(DROP)) {
        throw new SQLException(STATEMENT_NOT_SUPPORTED_ + sql);
    } else if (sql.startsWith(SELECT_CLIENT)) {

        Result<ClientRecord> result = create.newResult(CLIENT);
        result.add(create.newRecord(CLIENT));
        result.get(0).setValue(CLIENT.ID, 1L);
        result.get(0).setValue(CLIENT.SECRET_KEY, TEST_SECRET_KEY);
        mock[0] = new MockResult(1, result);

    } else if (sql.startsWith(SELECT_META)) {

        Result<MetaRecord> metaResult = create.newResult(META);
        metaResult.add(create.newRecord(META));
        metaResult.get(0).setValue(META.ID, 1L);

        metaResult.get(0).setValue(META.URL, SOME_URL);
        metaResult.get(0).setValue(META.KEY, KEY);
        metaResult.get(0).setValue(META.OPTION, keyId);
        mock[0] = new MockResult(1, metaResult);

    } else if (sql.startsWith(SELECT_KEY)) {

        Result<KeyRecord> keyResult = create.newResult(KEY);
        if (counter == FIRST_ITERARION_COUNTER_VALUE) {
            // first SELECT returns monkey, rest will return no results
            keyResult.add(create.newRecord(KEY));
            keyResult.get(0).setValue(KEY.ID, 1L);
            keyResult.get(0).setValue(KEY.VALUE, MONKEY);
            mock[0] = new MockResult(1, keyResult);
        } else {
            mock[0] = new MockResult(0, keyResult);
        }
        counter++;
    }

    return mock;
}
}

It works but looks bad.它有效,但看起来很糟糕。 To sum up my question is: How to return (using one provider) different results depending on the query and the number of query executions.总结我的问题是:如何根据查询和查询执行次数返回(使用一个提供程序)不同的结果。 Maybe this class is only for simple DSLContext mocking, not to mock whole DAO which uses many queries many times using one DSLContext.也许这个类仅用于简单的 DSLContext 模拟,而不是模拟使用一个 DSLContext 多次使用许多查询的整个 DAO。

I have done this and it is no fun - the mock in the end needs tests of its own... Another approach, is to enable the mock provider to be configurable with what to expect and what to return.我已经这样做了,但它并不有趣 - 最终模拟需要自己的测试......另一种方法是使模拟提供者能够配置期望和返回的内容。

provider.when(..).times(5).return(...) provider.when(...).times(5).return(...)

And so on... The return can take a generator as well as literal values.依此类推......返回可以采用生成器以及文字值。 The when could use regex as well as strings何时可以使用正则表达式以及字符串

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM