Изменение значения Mocked ResultSet при каждом выполнении оператора SQL

Я использую Mockrunner для создания ложного результирующего набора для оператора select. У меня есть цикл, который выполняет оператор выбора (который возвращает одно значение). Я хочу, чтобы результирующий набор возвращал разные значения каждый раз, но мне не удалось найти что-либо о том, как указать возвращаемое значение результирующего набора в зависимости от времени вызова оператора. Вот фрагмент кода псевдокода:

В тестовом коде:

String selectSQL = "someselectStmt";
StatementResultSetHandler stmtHandler = conn.GetStatementResultSetHandler();
MockResultSet result = stmtHandler.createResultSet();
result.addRow(new Integer[]{new Integer(1)});
stmtHandler.prepareResultSet(selectSQL, result);

В классе Actual Target:

Integer[] Results = getResults(selectSQL);

while(Results.length != 0){
    //do some stuff that change what gets returned in the select stmt
    Results = getResults(selectSQL)
}

По сути, я хотел бы вернуть что-то вроде 1 в первый раз, 2 на 2-й и ничего на 3-й. Я не нашел ничего такого, что смогло бы использовать это, чтобы достичь этого. Пересмотренный оператор выбора всегда будет возвращать независимо от того, какой последний набор результатов был связан с ним (например, если я создал два MockResultSets и связал оба с одним и тем же селектом stmt). Возможна ли эта идея?

1 ответ

Цикл управления потоком, работающий в Java и SQL

Если вы кодируете этот код на Java, способ сделать так, чтобы вызовы выполнения кода возвращали разные значения, последовательные результаты могут быть достигнуты с помощью оператора зацикливания потока управления, такого как цикл do-while. Эта ссылка на Википедию хорошо обсуждается с использованием контраста цикла do-while между реализациями в Java, а также в разных языках программирования.

Некоторые дополнительные влияния через наблюдение:

Ключ к вашей работе с Mockrunner инструмент:

Пересмотренный оператор выбора всегда будет возвращать независимо от того, какой последний набор результатов должен был быть связан с ним (например, если я создал два MockResultSets и связал оба с одним и тем же селектом выбора)

Это так, потому что SELECT оператор также должен измениться, иначе повторение запроса также повторит вывод результата. Подсказка в том, что ваш SQL существует в виде буквального строкового значения на протяжении всего выполнения кода. Строки могут быть изменены с помощью кода и простых операций с строками.

String selectSQL = "someselectStmt";
StatementResultSetHandler stmtHandler = conn.GetStatementResultSetHandler();
MockResultSet result = stmtHandler.createResultSet();
result.addRow(new Integer[]{new Integer(1)});
stmtHandler.prepareResultSet(selectSQL, result);

в добавок к selectSQL переменная, также добавьте строку для числовой переменной, чтобы отслеживать, сколько раз выполнялся оператор SQL:

Int queryLoopCount = 0;

В следующем целевом классе:

Integer[] Results = getResults(selectSQL);

while(Results.length != 0){
//do some stuff that change what gets returned in the select stmt
Results = getResults(selectSQL)
}

Попробуйте переписать это WHILE цикл управления, следуя этому примеру. В вашем псевдокоде вы будете извлекать те же данные из звонка getResults(selectSQL); потому что запрос остается неизменным при каждом проходе через код.

Настройка схемы тестирования и примера оператора SQL

Вот небольшая обработка с использованием одной таблицы MySQL, которая содержит выходные данные "testdata" для подачи в некоторый набор результатов. ID столбец может быть способом уникальной идентификации каждой отдельной записи или "контрольного примера"

SQL Fiddle

Настройка схемы MySQL 5.5.32:

CREATE TABLE testCaseData 
    (
     id int primary key,
     testdata_col1 int,
     testdata_col2 varchar(20),
     details varchar(30)
    );

INSERT INTO testCaseData
(id, testdata_col1, testdata_col2, details)
VALUES
(1, 2021, 'alkaline gab', 'First Test'),
(2, 322, 'rebuked girdle', '2nd Test'),
(3, 123, 'municipal shunning', '3rd Test'),
(4, 4040, 'regal limerick', 'Skip Test'),
(5, 5550, 'admonished hundredth', '5th Test'),
(6, 98, 'docile pushover', '6th Test'),
(7, 21, 'mousiest festivity', 'Last Test');

commit;

Запрос 1 Посмотрите на все данные испытаний:

SELECT id, testdata_col1, testdata_col2, details
  FROM testCaseData

Результаты:

| ID | TESTDATA_COL1 |        TESTDATA_COL2 |    DETAILS |
|----|---------------|----------------------|------------|
|  1 |          2021 |         alkaline gab | First Test |
|  2 |           322 |       rebuked girdle |   2nd Test |
|  3 |           123 |   municipal shunning |   3rd Test |
|  4 |          4040 |       regal limerick |  Skip Test |
|  5 |          5550 | admonished hundredth |   5th Test |
|  6 |            98 |      docile pushover |   6th Test |
|  7 |            21 |   mousiest festivity |  Last Test |

Запрос 2 Запрос только первой записи в таблице:

SELECT id, testdata_col1, testdata_col2, details
  FROM testCaseData
 WHERE id = 1

Результаты:

| ID | TESTDATA_COL1 | TESTDATA_COL2 |    DETAILS |
|----|---------------|---------------|------------|
|  1 |          2021 |  alkaline gab | First Test |

Запрос 3 Запрос определенной записи теста в таблице:

SELECT id, testdata_col1, testdata_col2, details
  FROM testCaseData
 WHERE id = 2

Результаты:

| ID | TESTDATA_COL1 |  TESTDATA_COL2 |  DETAILS |
|----|---------------|----------------|----------|
|  2 |           322 | rebuked girdle | 2nd Test |

Запрос 4 Возврат и ограничение размера выходного набора:

SELECT id, testdata_col1, testdata_col2, details
  FROM testCaseData
 WHERE id < 5

Результаты:

| ID | TESTDATA_COL1 |      TESTDATA_COL2 |    DETAILS |
|----|---------------|--------------------|------------|
|  1 |          2021 |       alkaline gab | First Test |
|  2 |           322 |     rebuked girdle |   2nd Test |
|  3 |           123 | municipal shunning |   3rd Test |
|  4 |          4040 |     regal limerick |  Skip Test |

Написание параметризованного оператора SQL

Я не знаю, дает ли это различие в синтаксисе те же самые результаты, что и ваш псевдокод, но я рекомендую его из ссылок на структуры кода, которые, как я знаю, уже работают.

set condition value before loop
do{
    // do some work
    // update condition value
}while(condition);

WHILE вместо этого условие находится в конце оператора и должно основываться на изменении значения, сделанного в циклическом блоке. Теперь мы введем вторую переменную, int, которая отслеживает количество итераций цикла:

String selectSQL = "someselectStmt";
String[] Results; = getResults(selectSQL);

// set condition value before loop 
queryLoopCount = 0

do{
    // do some work
    Results = getResults(selectSQL);

    // update condition value
    queryLoopCount = queryLoopcount + 1;

}while(queryLoopCount < 6);

куда selectSQL происходит от:

SELECT id, testdata_col1, testdata_col2, details
  FROM testCaseData
 WHERE id = 2;

И адаптируется со встроенным параметром для:

selectSQL = 'SELECT id, testdata_col1, testdata_col2, details
  FROM testCaseData
 WHERE id = ' + queryLoopCount;

Смешивание строковых и целочисленных значений может не быть проблемой, так как в этой ссылке на объединенные (+) значения предлагается: Все, что соединяется со строкой, преобразуется в строку (например, "вес = " + килограммы).

Идеи для особых случаев

  • Вы можете ввести свою собственную последовательность нумерации, чтобы заставить записи каждого случая циклически перемещаться по справочной таблице. Есть много возможностей, представляя ORDER BY заявление и изменение ключа ORDER BY значение.

  • Дело "Пропустить". В цикле Do-While добавьте оператор IF-THEN, чтобы условно пропустить конкретную запись.

    set condition value before loop
    do{
    
        if ( queryLoopCount <> 4 ) {
        // do some work}
    
        // update condition value
        queryLoopCount = queryLoopCount + 1;
    
    }while(condition);
    

    Используя цикл if-then, этот пример кода обработает все записи теста, но пропустит запись ID = 4 и продолжайте до тех пор, пока не будет выполнено условие цикла while.

Другие вопросы по тегам