0

我有一个看起来像这样的配置获取器。

def getForCountry[A](path: String, fallbackToDefault: Boolean)
                  (implicit loader: ConfigLoader[A], ac: AppContext): A = {
configuration.getOptional[A](s"${ac.country}.$path") match {
  case Some(value)                =>
    value
  case None if fallbackToDefault  =>
    configuration.get[A](path)
  case None if !fallbackToDefault =>
    throw new RuntimeException(s"${ac.country}.$path key not found in configuration")
}

相同方法的调用如下——

val countrySpecificConfig =
  configurationHelper.getForCountry[Map[String, String]]("googleCloudPlatform.jobConfig.demandBasedPricing", fallbackToDefault = false)

现在我想在我的单元测试中模拟 getForCountry 方法 -

when(configurationHelper
    .getForCountry[Map[String, String]]("googleCloudPlatform.jobConfig.demandBasedPricing", fallbackToDefault = false))
    .thenReturn(countryPricingWeekConfiguation)

令人惊讶的是,这种期望似乎没有正确设置。在执行测试时,模拟返回 null。

有关如何进行此操作的任何线索?如果您需要更多详细信息,请随时告诉我。

4

3 回答 3

1

你试过mockito-scala吗?如果您使用新语法,则会自动处理隐式(假设您使用惯用语法并且在测试和产品代码中解析了相同的实例)

此外,即使您使用传统语法,您的存根也会减少到

when(configurationHelper
    .getForCountry[Map[String, String]]
    (eqTo("googleCloudPlatform.jobConfig.demandBasedPricing"), eqTo(false))(*, *)
    .thenReturn(countryPricingWeekConfiguation)

或使用惯用语法

configurationHelper.getForCountry[Map[String, String]]
    ("googleCloudPlatform.jobConfig.demandBasedPricing",false)
    shouldReturn countryPricingWeekConfiguation

或者如果隐含在 test 和 prod 中不同(请注意,我也可以混合使用 arg 匹配器,如 * 和原始参数,如 'false')

configurationHelper.getForCountry[Map[String, String]]
    ("googleCloudPlatform.jobConfig.demandBasedPricing",false)(*,*)
    shouldReturn countryPricingWeekConfiguation
于 2019-03-17T18:42:36.987 回答
1

我强烈怀疑隐式的不同实例ConfigLoaderAppContext在您的实际方法调用中传递并模拟了一个。如果您使用的是 intellij,请通过启用它们来验证哪些隐式正在通过。要启用它们,请按ctr+alt+shift++

这是模拟您的情况的完整测试,效果很好:

test("mock example") {
    trait ConfigLoader[T] {}

    trait AppContext { def country: String }

    trait ConfigurationHelper {
      def getForCountry[A](x: String, fallbackToDefault: Boolean = true)(implicit loader: ConfigLoader[A], ac: AppContext): A
    }

    implicit val loader: ConfigLoader[Map[String, String]] = mock[ConfigLoader[Map[String, String]]]
    implicit val ctx: AppContext                           = mock[AppContext]
    val configurationHelper                                = mock[ConfigurationHelper]

    val mockedResult = Map("x" → "1")

    when(
      configurationHelper
        .getForCountry[Map[String, String]]("googleCloudPlatform.jobConfig.demandBasedPricing", fallbackToDefault = false)
    ).thenReturn(mockedResult)

    val countrySpecificConfig =
      configurationHelper
        .getForCountry[Map[String, String]]("googleCloudPlatform.jobConfig.demandBasedPricing", fallbackToDefault = false)

    countrySpecificConfig.foreach(println)
  }

// =========================== Output ====================
// (x,1)

于 2019-03-17T05:56:39.870 回答
0

非常感谢普里塔姆。以下代码似乎有效。

when(configurationHelper
    .getForCountry[Map[String, String]]
    (ArgumentMatchers.eq("googleCloudPlatform.jobConfig.demandBasedPricing"), ArgumentMatchers.eq(false))
    (ArgumentMatchers.any[ConfigLoader[Map[String, String]]](), ArgumentMatchers.any[AppContext]()))
    .thenReturn(countryPricingWeekConfiguation)
于 2019-03-17T16:22:23.233 回答