Изменение значения 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
столбец может быть способом уникальной идентификации каждой отдельной записи или "контрольного примера"
Настройка схемы 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.