Можем ли мы выполнить SQL без реального соединения с базой данных в Java?
Можем ли мы выполнить SQL без реального соединения с базой данных в Java? пример:
SELECT CASE
WHEN :param = 1 THEN 'TEST1'
WHEN :param = 2 THEN 'TEST2'
WHEN :param = 3 THEN 'TEST3'
END
AS RESULT
FROM DUAL
Я заменю:param во время выполнения в коде Java... Есть ли способ сделать это?
Я нашел эту ссылку: Как извлечь выбранные столбцы с учетом строки Oracle SQL?
но в этой ссылке нет быстрого решения
В настоящее время думаю о:- фиктивное соединение hsqldb и выполнить запрос sql. Но для этого требуется охват нового в памяти дб.
Есть ли лучшее и быстрое решение?
Спасибо
2 ответа
Я хочу выполнить выражение и получить данные.. Я пытаюсь с JSQLParser. Приведенный выше пример должен возвращать "Test1" в качестве вывода
но почему вы пытаетесь это сделать? Вы намерены протестировать свой запрос? или код, который вызывает запрос?
Если вы пытаетесь выполнить модульное тестирование объектов базы данных, вам может быть лучше поместить его в процесс и использовать среду модульного тестирования базы данных. Некоторая информация о модульном тестировании оракула. Я предполагаю, что оракул на основе двойного.
Если вы пытаетесь протестировать свой Java-код, вам нужно подумать о том, чтобы извлекать запрос непосредственно из метода, который вы пытаетесь протестировать, и программировать с интерфейсом, для которого вы можете предоставить "реальную" реализацию, а также макет или поддельная реализация. Таким образом, вы тестируете независимо от самого вызова db.
Пример того, что я имею в виду в коде, и извините, это будет немного грубо, так как я менее знаком с Java по сравнению с C#
скажем, у вас есть:
public class ClassINeedToTest {
public void myMethodThatNeedsTesting(int param1) {
// do some stuff
// implementation of sql code ... not real since I don't know how to call SQL from java
SELECT CASE
WHEN :param = 1 THEN 'TEST1'
WHEN :param = 2 THEN 'TEST2'
WHEN :param = 3 THEN 'TEST3'
END
AS RESULT
FROM DUAL
// potentially do some other stuff?
}
}
Итак, как указывалось выше, если вы хотите протестировать сам SQL, вам, вероятно, следует извлечь буквальный SQL, поместить его в хранимую процедуру и использовать инфраструктуру модульного тестирования, чтобы протестировать результат процедуры в нескольких сценариях, таких как значение параметра = 1, 2 и 3.
Но, если вы хотите проверить окружающие // Do stuff
и / или // potentially do some other stuff?
вне зависимости от подключения к базе данных, вам потребуется выполнить относительно простой рефакторинг.
Метод myMethodThatNeedsTesting
имеет зависимость от базы данных, которую мы должны абстрагироваться с помощью интерфейса, чтобы иметь возможность протестировать метод myMethodThatNeedsTesting
не полагаясь на реальное соединение с базой данных.
Это может выглядеть примерно так:
public interface ISomeInterface {
string getInfo(int param1);
}
Я определил выше, чтобы представлять то, что представляет запрос. Запрос требует параметр (param1) и возвращает скалярную строку (результат вашего запроса).
Учитывая этот интерфейс, вы можете изменить свой исходный класс, чтобы он выглядел примерно так:
public interface ISomeInterface {
string getInfo(int param1);
}
public class MySomeInterfaceImpl implements ISomeInterface {
@override
public string getInfo(int param1) {
// implementation of sql code ... not real since I don't know how to call SQL from java
SELECT CASE
WHEN :param = 1 THEN 'TEST1'
WHEN :param = 2 THEN 'TEST2'
WHEN :param = 3 THEN 'TEST3'
END
AS RESULT
FROM DUAL
}
}
public class ClassINeedToTest {
private ISomeInterface _myInterface;
public ClassINeedToTest(ISomeInterface iSomeInterface) {
_myInterface = iSomeInterface;
}
public void myMethodThatNeedsTesting(int param1) {
// do some stuff
_myInterface.getInfo(param1);
// potentially do some other stuff?
}
}
Выше вы можете видеть, что метод myMethodThatNeedsTesting
теперь больше не зависит напрямую от соединения с базой данных, а скорее от интерфейса. При этом теперь мы можем предоставить для целей тестирования макет, заглушку или подделку.
Пример подделки может быть:
public class MySomeInterfaceFake implements ISomeInterface {
@override
public string getInfo(int param1) {
if (param1 == 1)
return "TEST1";
if (param1 == 2)
return "TEST2";
if (param1 == 3)
return "TEST3";
}
Теперь с помощью вышеупомянутого фейка, вы передаете фальшивую реализацию в своем конструкторе, и вы можете проверить myMethodThatNeedsTesting
не полагаясь на соединение с базой данных.
Вышеупомянутый рефакторинг может быть определен как внедрение зависимостей, и он весьма полезен для слабой связи, что, среди прочего, приводит к более легкому тестированию кода.
Извините, если я испортил любой синтаксис в приведенном выше, опять же, ява не мой выбор языка:)
Как вы упомянули, JSqlParser: есть очень упрощенный пример оценки выражений. ( https://github.com/JSQLParser/JSqlParser/wiki/Example-of-expression-evaluation)
Вы можете расширить это, чтобы создать переводчика, который соответствует вашим потребностям. Поскольку JSqlParser является только парсером, это будет довольно сложной задачей.