Open kamilgregorczyk opened 5 years ago
I were not happy with the consequence of writing routes differently for unit testing as well.
I proofed a concept here https://github.com/laliluna/spark-mock-demo
The idea is to replace the service with a mock which allows to run tests without the server.
@Before
public void setup() {
SparkBuilder.initMock();
SparkApplication app = new SparkApplication();
app.init();
}
@Test
public void getReturnsEmptyArray() {
SparkClient client = MockSpark.getClient();
Response response = client.get("/hello");
assertEquals(200, response.status());
assertEquals("[]", response.body());
}
In order to implement this, we would need to make the service extend an interface and be swappable with a mock implementation. The classes SparkBuilder, MockSpark is only needed in the demo as the service is final.
If the idea is welcomed, I could try to implement this.
A couple things:
code:
get( '/hello', HelloService::get )
tests:
....
HelloService.get(mockReq, mockResp)
verify(mockResp).status(200)
....
setupRoutes()
... assert that '/get' points to the HelloService.get() method
However, you will note that the second test really just tests that the spark framework actually works. Which is silly - you shouldn't write a bunch of tests in your code for all the third party libraries you use.
So while there are nice reasons to have a Spark Service
class that you hand dependencies too (which you could then mock()), instead of having them created on the fly (as an option! the current behavior as the default behavior is nice too), I'm not sure what testing value you'd get out of this, other than enabling badly written tests. Maybe if there was a good example of a well-written test that this enabled, the design would be more clear.
Currently it's impossible to create custom request&response objects as constructors are protected.
This actually seems like the core of the issue.. however, the statement is also wrong, because you can mock Request & Response objects (e.g. with mockito).
I just verified with a test like so:
@Test
public void shouldAnswerWithTrue()
{
this.httpTestHandlerService.handleTestRequest(
mock(Request.class),
mock(Response.class)
);
}
Latest version, 2.9.1
Hi, It would be great if we could unitest spark directly through controllers, not by running whole server in-memory. Currently it's impossible to create custom request&response objects as constructors are protected.