【发布时间】:2018-06-15 01:37:00
【问题描述】:
我正在尝试模拟我与外部 API 的交互,该 API 检查令牌以查看用户是否被授权执行某些操作(它目前是作为 PoC 的单独 API,稍后将被移动到中间件中)
依赖项(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 框架模拟它。
【问题讨论】:
-
我缺少
MyHandler.handler的代码。它有什么作用?似乎也没有什么实际调用interactions。我怀疑您实际上需要在MyHandler中使用interactions,方法是将其作为构造函数参数传递,而不是扩展特征。然后你将能够传递一个将在测试期间调用的模拟。 -
@Eric
authenticateUser作为中间步骤在处理程序内部被调用。为不完整的代码道歉,已修复它并更改了某些消息。 -
问题依旧。您正在从与
MyHandler混合的特征中调用authenticateUser,而不是从您在ConfirmThat中构建的模拟对象中调用。
标签: scala mocking mockito aws-lambda specs2