当前位置: 首页 > 知识库问答 >
问题:

scala特性中的specs2模拟方法从未验证

澹台华晖
2023-03-14

我正在尝试模拟我与外部API的交互,该API检查令牌以查看用户是否有权执行某些操作(它目前是一个单独的API作为PoC,稍后将移动到中间件中)

受抚养人(SBT DSL)

"org.specs2" %% "specs2-core" % "4.2.0" % Test,
"org.specs2" %% "specs2-mock" % "4.2.0" % Test

测试

class MyHandlerSpec extends Specification with Mockito {
   def is = s2"""
     The first step is to check if the lambda is called on behalf of an 
     authenticated user. This is done by verifying that user token provided 
     as the Authorization header is valid by calling the auth API.

     Here, we can ${ConfirmThat().authLambdaWasCalled} by the handler
   """

 case class ConfirmThat() {
   def interactions = mock[Interactions]

  def authLambdaWasCalled = {
    val reqHandler = Request[Input](
       headers = Map[String, String](
          "Authorization" -> "Bearer gagagaga"
       )
      // millions of values that are not directly related
    )
    MyHandler.handler(reqHandler, null)
    there was one(interactions).authenticateUser(Some("gagagaga"))
  }
 }
}

代码

代码使用了一个MyHandler类,该类扩展了trait Interactions:

 trait Interactions extends MyServiceTrait with AuthServiceTrait {
    def authenticateUser(token: Option[String]): Future[Either[Errors, Boolean]] = {
  Future.successful(Right(true))
 }
}

class MyHandler extends Interactions with Utils {

  override def handler(request: Request[Input], c: Context): Response[Errors, Output] = { 
    //  get the auth token from the headers as an option, 
    //  there is a method in Utils that I unit tested
    //  it been omitted here for clarity

    val authFuture = authenticateUser(bearerToken)
  }  
}

错误

当我运行代码时,我看到以下错误:

The mock was not called as expected: 
[error]  Wanted but not invoked:
[error]  interactions.authenticateUser(
[error]      Some(gagagaga)
[error]  );
[error]  -> at com.lendi.lambda.MyHandlerSpec$ConfirmThat.$anonfun$authLambdaWasCalled$1(MyHandlerSpec.scala:71)
[error]  Actually, there were zero interactions with this mock. (MyHandlerSpec.scala:71)

我如何确保我可以:

a)将身份验证代码移动到MyHandler中,并使用Specs2提供的Mockito对MyHandler进行部分模拟

b)确保我模拟了交互并将交互注入到代码中,以便处理程序可以正确地模拟它。

c)使用DI框架(我应该为我的lambda使用Spring)注入交互并使用DI框架模拟它。

共有1个答案

宇文元明
2023-03-14

您需要将模拟对象传递给MyHandler

class MyHandler(interactions: Interactions) with Utils

然后

val interactions = mock[Interactions]
val myHandler = MyHandler(interactions)

MyHandler.handler(reqHandler, null)
 类似资料:
  • 我有一个java代码,我在其中调用scala对象的方法(依赖库的)。为了编写单元测试,我想模拟scala对象的方法调用 Operations.Scala

  • 基本上,我有以下几点: 我试着嘲笑这一点 但我犯了这个错误 我不想模拟映射的返回,因为我只希望来自这个特定方法的映射返回,而不是所有的映射。 你知道我是如何模仿以便它返回?

  • 我有一个带有rest apiendpoint的应用程序。我想为此编写测试用例。它遵循MVC架构。对于其中一个endpoint,我想在我的DAO类中模拟一个方法。 我的测试类的示例代码是: 此控制器将调用具有要模拟的方法的DAO层。我尝试在我的Test config类中使用如下mockito: 这样做的问题是,它模拟了整个DAO bean,所以对于其余的endpoint,它不调用DAO类方法,我的测

  • 问题内容: 我想测试以下方法: 帮助器类在哪里,该类将接受lambda形式的Functional Interface实现,并将其存储以供以后执行。 有没有一种方法可以通过mockito验证是否已使用特定的lambda表达式调用了模拟方法: 意思是,我可以写这样的测试: 此测试将导致断言错误:参数不同!通缉: 实际调用有不同的参数: 这是有道理的,因为Mockito尝试比较功能接口的两个不同实现,它

  • 问题内容: 我正在寻找一种与Mockito进行验证的方法,即在测试过程中与给定的模拟没有任何交互。对于具有验证模式的给定方法,很容易实现这一点,但是我还没有找到完整模拟的解决方案。 我真正想要实现的是:在测试中验证,没有任何内容打印到控制台上。jUnit的总体思路如下: A 有很多方法,我真的不想用单独的验证方法来验证每个方法,而… 因此,我希望,如果有一个简单的解决方案,鉴于我具有良好的测试覆盖

  • 我正在寻找一种方法来验证Mockito,在测试期间没有与给定的模拟进行任何交互。对于具有验证模式的给定方法,很容易实现这一点,但是我还没有找到完整模拟的解决方案。 我真正想要实现的是:在测试中验证,控制台上没有打印任何get。jUnit的总体思路如下: 一个有很多方法,我真的不想用单独的verify来验证每一个方法,对于。。。 所以我希望,如果有一个简单的解决方案,鉴于我有一个良好的测试覆盖率,我