Reputation: 907
given a simple Play 2.6.24 controller that handles a query parameter, i.e.
class MyController @Inject()(val controllerComponents: ControllerComponents) extends BaseController {
def foo(name: Option[String]= None) = { ... }
}
how should I test that foo
works properly and gets the correct query parameter, using ScalaTest, and without instantiating a FakeApplication
?
The closest I've come with, is the following:
class MyControllerSpec extends FlatSpec with StubControllerComponentsFactory with Results with Matchers {
private val controller = new MyController(stubControllerComponents())
it should "read `name` query parameter" in {
val result = controller.foo().apply(FakeRequest("GET", "/?name=test"))
contentAsString(result) shouldBe ...
}
}
but, as you know, this won't work: FakeRequest
content will get ignored, and I must explicitly call the controller as controller.foo(Some("test")).apply(...)
which doesn't look good, nor logical (why do I have to still provide a FakeRequest which won't get used?).
I have a feeling that, since it's done at routing level, I will have to use a FakeApplication... but maybe I'm wrong, and somebody knows a way to achieve what I'm looking for.
Thanks!
Upvotes: 0
Views: 505
Reputation: 1074
As far as I know, you can't test the query parameters provided in the FakeRequest unless you call the router which requires the actual app.
As you explained, controller.foo(Some("test")).apply(...)
would work because query parameters are extracted into method arguments, but it doesn't actually add much value to your tests.
Instantiating the app and testing with the router allows you to verify that clients will be able to call your method in the way it is supposed to be supported, which includes the path, request methods, headers, etc. This also makes it simpler to detect incompatible changes if you ever update how the controller renders the result.
Upvotes: 1