Good question. Not sure that it is the best option.
Suppose I have a contract which checks that entity supports basic CRUD
operations against the database - something like:
VerifyBasicPersistenceOperationsContract:
- Check that newly created entity is transient
- Check that entity can be saved to database (verifies mappings, db
schema, checks that an entity becomes non-transient and its ID is
populated with db primary key value etc)
- Check that entity can be loaded from database, by id
- Check that entity can be queried, by some property
- Check that changes in loaded entity can be saved to database
- Check that entity can be deleted from database (and the copy becomes
transient and ID is reset)
that kind of stuff. Now, ideally I would want to setup/teardown actions
to be performed before/after each individual check above. What you
propose is having something like:
public void TestOrder {
[ContractVerifier] private readonly IContractVerifier
persistenceOpsVerifier = new VerifyBasicPersistenceOperationsContract();
[SetUp]
public void Init() {
EnsureOrmFrameworkInitialized();
PurgeAllDataFromDb();
StartUnitOfWork();
}
[TearDown]
public void Terminate() {
EndUnitOfWork();
PurgeAllDataFromDb();
}
Which have a couple of drawbacks imho. First, I will have to introduce a
base TestFixture class with these setup/teardown methods (and probably
the verifier as well), and inherit TestOrder from it, to avoid code
duplication in each TestEntity class. (Or I may use generic fixture with
[Row] maybe). This is not very bad, I just wonder does it still conform
to mixin approach. Also, maybe the setup/teardown logic (the intent at
least) should be better encapsulated inside the contract itself (and
implementation supplied like new
VerifyBasicPersistenceOperationsContract<NHibernateTestContextProvider>)
so that contracts can be more easily reused between projects, perhaps
those using different ORMs?
Second, I might also wish to throw in the non-persistent contract
verifier in the mix (like equality one). I would hardly be glad to have
the database context going on and off on those checks. This might be
resolved by something like:
public abstract class BaseEntityFixture { new EqualityContractVerifier(); }
public abstract class BasePersistentEntityFixture : BaseEntityFixture {
new PeristentContractVerifier(); [SetUp]...}
if verifiers in a base fixture would not call the setup/teardown from
derived ones... but is it the best way?