我正在嘗試為 object1 下的函式撰寫單元測驗。
object Object1 {
def main(sysArgs: Array[String]): Unit = {
val inputDF: DataFrame = UtilObject.getInput()
}
}
object UtilObject {
def getInput(){
...
}
}
要撰寫單元測驗,我使用的是 MockitoSugar。
"object1Main" should "should make correct calls" in {
val inputArgs = Array("abc")
val util = mock[UtilObject.type]
when(util.getInput().thenReturn(inputData))
Object1.main(inputArgs)
}
在運行測驗時,它不考慮 util mock,只執行 getInput() 函式。
我想我在這里錯過了某種注射。有任何想法嗎?
提前致謝!
uj5u.com熱心網友回復:
從概念上講,模擬 Scala 物件應該是不可能的。Scala 中的物件是純單例。這意味著任何時候都只能有一個該型別的成員。
mockito-scala可以通過反射模擬 Scala 物件。我將使用結果型別,而不是 a ,但想法是相同的:StringDataFrame
object UtilObject {
def getInput(): String = {
// ...
"done"
}
}
object Object1 {
def main(sysArgs: Array[String]): String = {
val inputDF: String = UtilObject.getInput()
inputDF
}
}
// in test file:
"object1Main" should {
"should make correct calls" in {
val inputArgs = Array("abc")
withObjectMocked[UtilObject.type] {
UtilObject.getInput() returns "mocked!"
Object1.main(inputArgs) shouldBe "mocked!"
}
Object1.main(inputArgs) shouldBe "done"
}
}
這僅在withObjectMocked.
通常如此強大的技術往往會被過度使用或誤用,所以我一般不推薦它們,除非設計無法重構。
幸運的是,您可以:最簡單的方法是將依賴注入與類或函式一起使用。對于具有類的 DI,您需要將被模擬的物件轉換為類:
class UtilObject {
def getInput(): String = {
// ...
"done"
}
}
object Object1 {
def main(sysArgs: Array[String], ut: UtilObject): String = {
val inputDF: String = ut.getInput()
inputDF
}
}
// in test file:
"object1Main" should {
"should make correct calls" in {
val inputArgs = Array("abc")
val util = mock[UtilObject]
when(util.getInput()).thenReturn("mocked!")
Object1.main(inputArgs, util) shouldBe "mocked!"
}
}
對于具有函式的 DI,您需要將要模擬的方法提升為函式:
object UtilObject {
def getInput(): String = {
// ...
"done"
}
}
object Object1 {
def main(sysArgs: Array[String], f: () => String = UtilObject.getInput): String = {
val inputDF: String = f()
inputDF
}
}
// in test file:
"object1Main" should {
"should make correct calls" in {
val inputArgs = Array("abc")
val f = mock[() => String]
when(f()).thenReturn("mocked!")
Object1.main(inputArgs, f) shouldBe "mocked!"
}
}
由于該函式不接受任何引數,因此您可以將其轉換為按名稱引數。我會把它留給你。
另一種方法是使用您要模擬的方法創建一個特征,并用物件擴展它。但現在Object1需要成為一個類并參考被模擬的物件:
object UtilObject extends Utils {
def getInput(): String = {
// ...
"done"
}
}
trait Utils {
def getInput(): String
}
class Object1 {
val uo: Utils = UtilObject
def main(sysArgs: Array[String]): String = {
val inputDF: String = uo.getInput()
inputDF
}
}
// in test file:
"object1Main" should {
"should make correct calls" in {
val classUnderTest = new Object1 {
override val uo = mock[Utils]
}
val inputArgs = Array("abc")
when(classUnderTest.uo.getInput()).thenReturn("mocked!")
classUnderTest.main(inputArgs) shouldBe "mocked!"
}
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/504754.html
