JOOQ MockDataProvider语言 - 如何根据某些条件返回不同的mock



最近我正在使用JOOQ MockDataProvider实现一个单元测试。当我想在具有许多选择的DAO中使用模拟提供程序时,我必须使用许多if-else语句。

根据:http://www.jooq.org/doc/latest/manual/tools/jdbc-mocking,我只需要检查我的SQL是否开始与一些查询。我在DAO中使用的sql可以以3种不同的方式开始,所以我使用了非常复杂的if-else结构。

第二件事-我希望我的MockDataProvider只在第一次执行SQL时返回一些模拟结果,然后不返回任何结果-在DAO中循环迭代5次,每次我的DAO都应该检查数据库中的某些内容。我不知道如何模拟这种行为,所以我使用了简单的counter -但它看起来很糟糕,我希望它能以一种好的方式实现。下面是我的代码:

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;
}
}

它工作,但看起来不好。我的问题总结如下:如何根据查询和查询执行次数返回(使用一个提供程序)不同的结果。也许这个类只是用于简单的DSLContext模拟,而不是模拟使用一个DSLContext多次使用许多查询的整个DAO。

我已经这样做了,这一点也不好玩- mock最终需要自己进行测试…另一种方法是使模拟提供程序可以配置期望的内容和返回的内容。

provider.when(. .)同学(5).return(…)

等等……返回值可以是一个生成器,也可以是文字值。when可以使用正则表达式和字符串

最新更新