Этот ответ использует только scalatest и не влияет на исходный код:
Базовое решение:
Допустим, у вас есть этот класс src (тот, который вы хотите протестировать и для которого вы хотите имитировать зависимость):
package com.my.code
import com.lib.LibHelper
class MyClass() {
def myFunction(): String = LibHelper.help()
}
и эта зависимость библиотеки (которую вы хотите имитировать/переопределить при тестировании MyClass):
package com.lib
object LibHelper {
def help(): String = "hello world"
}
Идея состоит в том, чтобы создать класс в вашей тестовой папке, который будет переопределять/затенять библиотеку. Класс будет иметь то же имя и тот же пакет, что и тот, который вы хотите имитировать. В src/test/scala/com/external/lib
вы можете создать LibHelper.scala
, который содержит этот код:
package com.lib
object LibHelper {
def help(): String = "hello world - overriden"
}
И таким образом вы можете протестировать свой код обычным способом:
package com.my.code
import org.scalatest.FunSuite
class MyClassTest extends FunSuite {
test("my_test") {
assert(new MyClass().myFunction() === "hello world - overriden")
}
}
Улучшенное решение, которое позволяет настраивать поведение макета для каждого теста:
Предыдущий код ясен и прост, но имитируемое поведение LibHelper одинаково для всех тестов. И может потребоваться, чтобы метод LibHelper производил разные результаты. Таким образом, мы можем рассмотреть возможность установки изменяемой переменной в LibHelper и обновления переменной перед каждым тестом, чтобы установить желаемое поведение LibHelper. (Это работает, только если LibHelper является объектом)
Затеняющий LibHelper (тот, что находится в src/test/scala/com/external/lib) следует заменить на:
package com.lib
object LibHelper {
var testName = "test_1"
def help(): String =
testName match {
case "test_1" => "hello world - overriden - test 1"
case "test_2" => "hello world - overriden - test 2"
}
}
И самым маленьким классом должен стать:
package com.my.code
import com.lib.LibHelper
import org.scalatest.FunSuite
class MyClassTest extends FunSuite {
test("test_1") {
LibHelper.testName = "test_1"
assert(new MyClass().myFunction() === "hello world - overriden - test 1")
}
test("test_2") {
LibHelper.testName = "test_2"
assert(new MyClass().myFunction() === "hello world - overriden - test 2")
}
}
Очень важная точность, так как мы используем глобальную переменную, обязательно заставить scalatest запускать тест последовательно (не параллельно). Связанный параметр scalatest (который должен быть включен в build.sbt):
parallelExecution in Test := false
person
Xavier Guihot
schedule
01.03.2018