-
Notifications
You must be signed in to change notification settings - Fork 21
Description
Hi github
I like assertj-db and use it on a regular basis.
There is an improvement I would like to see if possible; hence this feature request.
I often find myself having to use both assertj-db assertions and assertj-core assertions in the same class.
Most often it is :
- Testing insert/update/delete methods : I use AssertJ DB to verify DB state
- Testing select methods : I use AssertJ core to assert on the result
However both entry point are called the same (Assertions.assertThat) but come from different packages.
The result is I can only have one assertThat as a static import.
I end up with something like this :
import static org.assertj.db.api.Assertions.assertThat;
import org.assertj.core.api.Assertions;
...
myDao.insert(stuff);
Request request = assertDbConnection
.request("select foo from bar where toto = ?")
.parameters("dummy")
.build();
RequestAssert assert = assertThat(request); // static import there - which is what I would like everywhere
// perform some db assertion there
...
String t = myDao.selectStuff();
Assertions.assertThat(t).isEqualTo(...); // non static import there - both static import with same method name can't coexist
It is not the end of the world, but I was wondering if some improvements could not be made.
I looked into it, and found that AssertJ provide the interface AssertProvider<A> which maybe could be used.
Springframework uses it to provide powerful assertions for their own assertions objects (like in the mvc test infrastructure), while retainaing the integration with Assertions class from AssertJ core.
My understanding is that :
- The
AssertProviderimplementation wraps the custom assertion object - for AssertJ DB that would be RequestAssert and its siblings AssertProviderreturns the custom assertion object from its only methodAssertProvideris then to be passed to theorg.assertj.core.api.Assertions.assertThatmethod- The result of that call is the custom assertion object itself, which we can use for the custom assertions
This would look like this :
public static class RequestAssertProvider implements AssertProvider<RequestAssert> {
private RequestAssert requestAssert;
public RequestAssertProvider(RequestAssert requestAssert) {
this.requestAssert = requestAssert;
}
@Override
public RequestAssert assertThat() {
return this.requestAssert;
}
}
Given that, we would need a clean way to :
- Build the
RequestAssertfrom theRequest - Build the
RequestAssertProviderfrom theRequestAssert - Then pass it to the
org.assertj.core.api.Assertions.assertThatmethod
Then in the test class we would only need the assertions class from assertj core :
import org.assertj.core.api.Assertions;
...
RequestAssertProvider assertProvider = ...; // find a way to build this cleanly like we usually build Request
RequestAssert = assertThat(assertProvider);
...
We can then do DB assertions as usual, while retaining the ability to perform core AssertJ assertions without the hassle of the double imports.
Now I'm not naïve enough to think I am the first to consider that problem.
So maybe there is a catch; which I would be interested to know of.
I forked the AssertJ DB repo and gave it a try anyway.
I wrote the RequestAssertProvider like mentioned; as a static inner class for the Request class.
I then altered the Request.Builder by adding this method :
public RequestAssertProvider buildAssert() {
Request obj = this.build();
RequestAssert requestAssert = new RequestAssert(obj).as(getDescription(obj));
return new RequestAssertProvider(requestAssert);
}
Seems like it works.
But it looks like I introduced a cyclic dependency between the Request and RequestAssert classes
Maybe its bad, maybe its not; I'm not sure.
If it's not, I'm willing to iterate on it and submit it as a PR.
Or maybe try another approach.
So would this be useful, and would this be possible ?
What do you think ?
Thank you for reading me