如何模拟ActionBuilder的BodyParser.Default参数?

时间:2019-07-25 08:44:35

标签: scala testing playframework mocking play-framework-2.7

我想为以下控制器编写测试。

   class DashboardController @Inject()(cc: ControllerComponents,
                                    dashboardDataService: DashboardService,
                                    authenticationAction: AuthenticationAction) 
                                    extends AbstractController(cc) 
                                    {
    def dashboard(): Action[AnyContent] = authenticationAction.async {
        implicit request =>
        Ok(views.html.dashboard(dashboard)))
    }
}

当我尝试使用new AuthenticationAction(mockProperties, mock[BodyParsers.Default])之类的模拟参数在测试内部创建Action builder(AuthenticationAction)实例时,出现此错误:

when() requires an argument which has to be 'a method call on a mock'.
[error]    For example:
[error]        when(mock.getArticles()).thenReturn(articles);
[error]
[error]    Also, this error might show up because:
[error]    1. you stub either of: final/private/equals()/hashCode() methods.
[error]       Those methods *cannot* be stubbed/verified.
[error]       Mocking methods declared on non-public parent classes is not supported.
[error]    2. inside when() you don't call method on mock but on some other object.

我尝试创建BodyParsers.Default的实例,而不是模拟它, 但是它需要一些我无法传递的隐式参数。

如何创建BodyParsers.Default类的实例?

 val mockProperties = mock[ApplicationConfig]
    mockAuthenticationAction returns new AuthenticationAction(mockProperties, mock[BodyParsers.Default])

2 个答案:

答案 0 :(得分:0)

stubControllerComponents提供了各种测试存根,例如包括解析器

val cc = stubControllerComponents()
cc.parsers.default

提供BodyParser[AnyContent]

答案 1 :(得分:0)

最后,我能够弄清楚。 我们必须使用调用Action Builder的方法创建另一个类

class AuthenticationFactory @Inject() (properties: ApplicationConfig, 
parser: BodyParsers.Default) {

   def authenticate = new AuthenticationAction(properties, parser)

}

发布嘲讽效果很好

mockAuthenticationAction.authenticate returns new AuthenticationAction(mockProperties, mock[BodyParsers.Default])