DueTo(...) how to express multiple possible cases...
Closed this issue · 4 comments
Hi Folks,
Here is a special case I'm facing.
I'm currently probating a software dealing with different data store layers (understand DB).
My requirement is to keep the test as much as generic as possible to keep one set of test for all, while verifying inner exception.
Depending on the SQL Database, the inner exception can change from OleDbException, to SQLException -(or any other depending on the DB Provider)...
Hence the DueTo() is limiting me to only one option, such as this:
Check.ThatCode(() => { DAL.ExecuteSQLStatment(); }).Throws<DataException>().WithMessage("Data Access Layer exception: see Inner Exception for details.").And.DueTo<OleDbException>()
or this:
Check.ThatCode(() => { DAL.ExecuteSQLStatment(); }).Throws<DataException>().WithMessage("Data Access Layer exception: see Inner Exception for details.").And.DueTo<SQLException>();
How can we express this in one line ?... avoiding to drill the component to retrieve the DB Layer express this in verbose multiple lines (if + if + if ...)
Suggestion ONE:
Check.ThatCode(() => { DAL.ExecuteSQLStatment(); }).Throws<DataException>().WithMessage("Data Access Layer exception: see Inner Exception for details.").And.DueTo<SQLException>().Or.DueTo<OleDbException>();
In another hand:
'
.And.DueTo().And.DueTo()
'
is checking the inner of the inner exception...
Which is not formally consistent with syntax I proposed.
Maybe, Suggestion TWO:
'
object[] expectedExcpetionTypes = new object[] { typeof(OleDbException), typeof(SqlException) };
......And.DueTo().And.DueTo();
'
But I don't really like the unrigorous option of the latter.
Any idea ?
To this day, we are not able to support the full boolean logic scope and NFluent does not offer 'Or'. Obviously, this is not a naming issue, so using 'And' instead is no solution :-)
I share your point of view that option two is not elegant, but it can be implemented.
I have a third option in mind, but I would like to understand your use case better before going back to how to implement it.
My main question is: why do you care so much about the inner exception in those cases?
What do you plan to achieve with this test?
Second question is: why can't you either identify the underlying DAL and perform the adequate check or explicit the DAL to be used and perform the adequate check (or checks)?
Hi dupdob,
To your question 1:
I care about the inner because I want to make sure the error scope is the ones I expect. For instance, the DAL is dealing with two db engine, the call perform an update, I want to make sure the one or both does not fail for the bad reason: one for relation constraints (expected), the other one for granting (unexpected).
To your second question:
If from a usage point of view (the test) I select the couple DAL/DbEngine. This means I expose this capability to the client which is not desired because I want to make the client agnostic of this and because it's potentially not safe. For this reason, the selection of the couple is done externally.
In another way, it is a design choice: If I tell the DAL to check and manage the db specificities, then the system is closed to a 'finished' set of couples DAL/db engines.
I prefer then to let the tests validate my new DAL/newdbengine couple without touching the DAL.
Thus, up to the test to qualify or not the dbengine thru the DAL.
Finally, It's a matter of genericity/open system/economy of source code.
But anyway, more than an issue, it was just a question of feasibility or not. In that special case a none SDHP is ok too. Just, it taste be better to me with it, that's all.
May you have another way in mind, tell me :-)
Hi
coming back to this issue. I propose to add variants to _DueTo<>():
DueToOneOf<T1,T2>()
DueToOneOf<T1,T2,T3>()
DueToOneOf<T1,T2,T3,T4>()
...
in your case: ....DueToOneOf<OleDbException, SqlException>()
Ok with that?
Added DueToAnyFrom(type1, type2)
Check.ThatCode( () => ...).ThrowsAny().DueToAnyFrom(typeof(Exception), typeof(ArgumentException));