簡體   English   中英

在Scala中模擬新對象的創建

[英]Mock new object creation in Scala

我想為以下scala類編寫單元測試。 在以下實現中,QueryConfig是最終案例類。

class RampGenerator {
  def createProfile(queryConfig: QueryConfig): String = {
    new BaseQuery(queryConfig).pushToService().getId
  }
}

我寫的單元測試是這個

@RunWith(classOf[JUnitRunner])
class RampGeneratorTest extends FlatSpec with Matchers {
  "createProfile" must "succeed" in {
    val rampGenerator = new RampGenerator()

    val queryConfig = QueryConfig("name", "account", “role")
    val baseQuery = mock(classOf[BaseQuery])
    val profile = mock(classOf[Profile])

    when(new BaseQuery(queryConfig)).thenReturn(baseQuery)
    when(baseQuery.pushToService()).thenReturn(profile)
    when(profile.getId).thenReturn("1234")
    val id = rampGenerator.createProfile(queryConfig)
    assert(id.equals("1234"))
  }
}

目前,它給出了以下異常,這是預料之中的,因為我沒有在何時使用模擬類。 如何模擬新的實例創建?

org.mockito.exceptions.misusing.MissingMethodInvocationException: 
when() requires an argument which has to be 'a method call on a mock'.
For example:
    when(mock.getArticles()).thenReturn(articles);

有兩種選擇:

  1. 使用powermockito模擬構造函數(有關詳細信息,請參閱此問題
  2. 外部化對象創建

關於第二個選項的內容要多一些-這實際上是一種測試技術,可以在多種情況下提供幫助(幾個示例:您的示例,創建akka actor並聲明層次結構)-因此,將其包含在“工具箱”。

在您的情況下,它將如下所示:

class RampGenerator(queryFactory: QueryFactory) {
   def createProfile(queryConfig: QueryConfig) = queryFactory.buildQuery(queryConfig).pushToService().getId()
}

class QueryFactory() {
   def buildQuery(queryConfig: QueryConfig): BaseQuery = ...
}


@RunWith(classOf[JUnitRunner])
class RampGeneratorTest extends FlatSpec with Matchers {
  "createProfile" must "succeed" in {
    val rampGenerator = new RampGenerator()

    val queryConfig = QueryConfig("name", "account", “role")
    val queryFactory = mock(classOf[QueryFactory])
    val profile = mock(classOf[Profile])
    val baseQuery = mock(classOf[BaseQuery])

    when(queryFactory.buildQuery(queryConfig)).thenReturn(baseQuery)
    when(baseQuery.pushToService()).thenReturn(profile)
    when(profile.getId).thenReturn("1234")
    val id = rampGenerator.createProfile(queryConfig)
    assert(id.equals("1234"))
  }
}

請注意,查詢工廠不必是單獨的工廠類/類的層次結構(當然,它不需要像抽象工廠模式那么重的東西-盡管可以使用它)。 特別是,我的初始版本僅使用queryFactory: QueryConfig => BaseQuery函數,但模仿者不能模仿函數...

如果您希望直接(通過函數)注入工廠方法,則Scalamock支持模擬函數

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM