I'm new to both django and unit-testing, and I'm trying to build unit-tests for my models but have been having some difficulty.
I have several models working closely together:
Resource
which will maintain a file resource
MetadataField
which represents a metadata field that can be added to resources, corresponds to a table full of fields
MetadataValue
Matches MetadataField IDs with Resource IDs and a corresponding value, this is an intermediary table for the Resource - MetadataField many-to-many relationship
MetadataSchema
represents a schema consisting of many MetadataFields
. Each Resource
is assigned a MetadataSchema
which controls which MetadataFields
it is represented by
Relationships:
Resource - MetadataField : Many-to-Many through MetadataValue
MetadataValue - MetadataSchema : Many-to-Many
Resource - MetadataSchema : One-to-Many
I'm not sure how to write tests to deal with these models. The model testing in the Test Driven Django tutorial seems to mostly cover initializing the objects and verifying attributes. If I do any setting up of these objects though it requires the use of all the others, so the tests will all be dependent on code that they're not meant to be testing. e.g. if I wish to create a resource, I should also be assigning it a metadata schema and values for fields in that schema.
I've looked around for good examples of unit tested models in django but haven't been able to find anything (the django website doesn't seem to have unittests, and these projects all either have poor/missing testing or in a couple cases have good testing but almost no models used.
Here are the possible approaches I see:
- Doing a lot of Mocking, to ensure that I am only ever testing one class, and keep the unit tests on the models very simple, testing only their methods/attributes but not that the relationships are functioning correctly. Then rely on higher level integration tests to pick up any problem in the relationships etc.
- Design unittests that DO rely on other functionality, and accept that a break in one function will break more than one test, provided it remains easy to see where the fault occurred. So i would perhaps have a method testing whether I can successfully add a
MetadataValue
to a resource, which would require setting up at least oneMetadataSchema
andResource
. I could then use atry - except
block to ensure that if the test fails before the assertions dealing with what I'm actually meant to be testing, it gives a specific error message suggesting the fault lies elsewhere. This way I could quickly scan multiple failed test messages to find the real culprit. It wouldn't be possible to do this separation reliably in every test though
I'm having a hard time getting my head round this, so I don't know if this all makes sense, but if there are best practices for this sort of situation please point me to them! Thanks