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

В моем искровом приложении есть метод, который загружает данные из базы данных 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 или другой способ лучше, чем издевательство, чтобы протестировать этот метод?


person rogue-one    schedule 26.03.2018    source источник
comment
@himanshuIIITian, ​​это не дубликат этого вопроса. Мой вопрос очень специфичен для случая использования, когда мой метод загружает данные только из базы данных и как я могу проверить его с помощью макета или любого другого метода, если это возможно. Вопрос, который вы связали, не говорит о том, как имитировать это или как справиться с очень конкретным сценарием.   -  person rogue-one    schedule 26.03.2018
comment
Ok! Я думал, что это похоже на это. Приносим извинения за путаницу.   -  person himanshuIIITian    schedule 26.03.2018
comment
Что именно вы хотите протестировать? Если запрос можно выполнить? Честно говоря, я бы не стал тестировать этот метод, потому что он не содержит никакой логики, реализованной вами (без обид). Вы просто запускаете некоторую логику, предоставленную Spark - это должно быть проверено на их стороне. Если вы все равно хотите это проверить, вы можете использовать встроенную базу данных.   -  person TobiSH    schedule 26.03.2018
comment
Или я неправильно понял ваш вопрос, и вы спрашиваете, кому создавать спарк-сессию? Вот так: SparkSession.builder().getOrCreate()   -  person TobiSH    schedule 26.03.2018
comment
Честно говоря, я бы не стал тестировать этот метод, потому что он не содержит никакой логики, реализованной вами ... что, если у меня два параметра поменяны местами ... вот так session.read.jdbc(s"(${input.selectQuery}) T0", input.jdbcUrl .. .. Я согласен, что тестировать этот код не очень важно. ... но, тем не менее, в его тестировании действительно есть какая-то ценность ..   -  person rogue-one    schedule 27.03.2018


Ответы (2)


В вашем случае я бы рекомендовал не издеваться над 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)
  }
}
person TobiSH    schedule 26.03.2018

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

person alecswan    schedule 01.11.2019