Mocking SparkSession для модульного тестирования

В моем приложении spark есть метод, который загружает данные из базы данных MySQL. метод выглядит примерно так.

trait DataManager {

val session: SparkSession

def loadFromDatabase(input: Input): DataFrame = {
            session.read.jdbc(input.jdbcUrl, s"(${input.selectQuery}) T0",
              input.columnName, 0L, input.maxId, input.parallelism, input.connectionProperties)
    }
}

Метод не делает ничего, кроме выполнения jdbc метод и загружает данные из базы данных. Как я могу проверить этот метод? Стандартный подход заключается в создании макета объекта session который является примером SparkSession, Но с тех пор SparkSession есть частный конструктор, я не смог издеваться над ним с помощью ScalaMock.

Основной вопрос здесь заключается в том, что моя функция является чисто побочной функцией (побочным эффектом является извлечение данных из реляционной базы данных), и как я могу выполнить модульное тестирование этой функции, если у меня есть проблемы с подделкой SparkSession,

Так есть ли способ, которым я могу издеваться SparkSession или любой другой лучший способ, чем издеваться, чтобы проверить этот метод?

1 ответ

Решение

В вашем случае я бы рекомендовал не издеваться над SparkSession. Это будет более или менее издеваться над всей функцией (что вы можете сделать в любом случае). Если вы хотите протестировать эту функцию, я бы предложил запустить встроенную базу данных (например, H2) и использовать настоящую SparkSession. Для этого вам нужно предоставить SparkSession вашему DataManager,

Непроверенный эскиз:

Ваш код:

class DataManager (session: SparkSession) {
         def loadFromDatabase(input: Input): DataFrame = {
            session.read.jdbc(input.jdbcUrl, s"(${input.selectQuery}) T0",
            input.columnName, 0L, input.maxId, input.parallelism, input.connectionProperties)
         }
    }

Ваш тест-кейс:

class DataManagerTest extends FunSuite with BeforeAndAfter {
  override def beforeAll() {
    Connection conn = DriverManager.getConnection("jdbc:h2:~/test", "sa", "");
    // your insert statements goes here
    conn.close()
  }

  test ("should load data from database") {
    val dm = DataManager(SparkSession.builder().getOrCreate())
    val input = Input(jdbcUrl = "jdbc:h2:~/test", selectQuery="SELECT whateveryounedd FROM whereeveryouputit ")
    val expectedData = dm.loadFromDatabase(input)
    assert(//expectedData)
  }
}

Вы можете использовать mockito scala для имитации SparkSession, как показано в этой статье.

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