【问题标题】:need help in understanding if the way I am testing a function is correct需要帮助以了解我测试功能的方式是否正确
【发布时间】:2019-03-31 18:30:38
【问题描述】:

我写了这个函数,当用户点击一个链接时会调用它。该函数基本上创建了一个更改了一个字段的用户数据副本(从而保持原始值不变,即不可变),然后用新值更新数据库

def confirmSignupforUser(user:User):Future[Option[User]] = {
    println("confirming user: "+user)
        val newInternalProfile = user.profile.internalProfileDetails.get.copy(confirmed=true)//new data which should be added in the database
        println("old internal profile: "+user.profile.internalProfileDetails.get)
        println("new internal profile: "+newInternalProfile)
        val newProfile = UserProfile(Some(newInternalProfile),user.profile.externalProfileDetails)
        println("old profile: "+user.profile)
        println("new profile: "+newProfile)
        val confirmedUser = user.copy(profile=newProfile)
        for(userOption <- userRepo.update(confirmedUser)) yield { //database operation
          println("returning modified user:"+userOption)
          userOption
      }
  }

为了测试代码,我编写了以下规范

"confirmSignupforUser" should {
    "change confirmed status to True" in {
      val testEnv = new TestEnv(components.configuration)
      val externalProfile = testEnv.externalUserProfile
      val internalUnconfirmedProfile = InternalUserProfile(testEnv.loginInfo,1,false,None)
      val internalConfirmedProfile = internalUnconfirmedProfile.copy(confirmed=true)
      val unconfirmedProfile = UserProfile(Some(internalUnconfirmedProfile),externalProfile)
      val confirmedProfile = UserProfile(Some(internalConfirmedProfile),externalProfile)
      val origUser = User(testEnv.mockHelperMethods.getUniqueID(),unconfirmedProfile)
      val confirmedUser = origUser.copy(profile = confirmedProfile)
      //the argument passed to update is part of test. The function confirmSignupforUser should pass a confirmed profile
      when(testEnv.mockUserRepository.update(confirmedUser)).thenReturn(Future{Some(confirmedUser)})
      //// await is from play.api.test.FutureAwaits
      val updatedUserOption:Option[User] = await[Option[User]](testEnv.controller.confirmSignupforUser(origUser))
      println(s"received updated user option ${updatedUserOption}")
      updatedUserOption mustBe Some(confirmedUser)


    }
  }

我不确定我是否正确测试了该方法。我可以检查confirmed 字段是否已更改的唯一方法是查看confirmSignupforUser 的返回值。但我实际上是在模拟该值,并且我已经在模拟值(when(testEnv.mockUserRepository.update(confirmedUser)).thenReturn(Future{Some(confirmedUser)}))中将字段confirmed 设置为true

我知道代码有效,因为在上面的模拟中,update 方法需要confirmedUser,换句话说,confirmed 字段设置为true 的用户。因此,如果我的代码不工作,update 将被调用 userconfirmed 字段为 falsemockito 将失败。

这是测试方法的正确方法还是有更好的方法?

【问题讨论】:

    标签: scala mockito playframework-2.6


    【解决方案1】:

    您无需在测试中初始化internalConfirmedProfile。重点是从confirmed=false开始,运行confirmSignupforUser方法,确保输出为confirmed=true

    你应该检查两件事:

    1. 检查返回值是否有confirmed=true(你这样做)
    2. 检查存储库是否使用confirmed=true 保存了该用户(您不检查)。要检查您是否需要在最后从存储库中加载用户。

    【讨论】:

    • 当我在模拟数据库时,我需要模拟update 方法的返回值。为此我需要internalConfirmedProfile
    • 这应该由 mockUserRepository 来处理,而不是由测试来处理,即你的 mockUserRepository.update(o) 应该用 o 更新它的私有状态。如果您向代码展示了您的 mockUserRepository 是如何创建的,我将能够提供一些建议。
    • 最简单的方法是模拟update 方法以返回像mockUserRepository.update = x =&gt; future_with_result(Some(x)) 这样传入的任何内容,但这还不够,因为您还应该检查点(2)。
    猜你喜欢
    • 1970-01-01
    • 2018-08-11
    • 2018-04-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-01-11
    • 1970-01-01
    相关资源
    最近更新 更多