Silicon-Age / opal

Silicon Age's ORM layer.
0 stars 0 forks source link

Make opals work with automated testing #12

Open jonahgreenthal opened 1 month ago

jonahgreenthal commented 1 month ago

There should be some way for automated tests to interact with opals.

One idea that has been floated is to have some sort of "test mode" that reads from a database but never writes anything — changes only live in memory. This is vulnerable to SoftReferences being cleared, but it's probably good enough. For extra safety, it could be augmented by using a database user that doesn't have permission to insert, update, or delete.

It would be nice to be able to operate without any database at all, which the above idea wouldn't support.

rhentzel commented 1 month ago

I guess there's no reason that this couldn't be extended to have an even more extreme mode in which database reads are skipped (so nothing appears to exist) and no Connection is ever requested from the DataSource.

The user would not have access to "constant" rows like the HIGH_SCHOOL Audience (and would not be able to create them for Opals that are uncreatable).

This will sound snarky, but I'm a little unsure of what it means to "be nice" to be able to operate without a database at all. Is it that we want our code to be extraordinarily abstracted from its persistent store? So that we could swap in some sort of filesystem-based database and everything would still work? Or we just think it's inelegant/dangerous/whatever to rely on having test/CI access to a database with "the basics" of our schema and raw data?

If we got his route, it's probably only a little more work to have the various Factories that maintain caches understand "test mode" and switch to using hard references in place of SoftReferences.

jonahgreenthal commented 1 month ago

I don't think it's good for unit testing to rely on access to a database, in several senses:

As a concrete example, think of what I talked about before with testing Contact.getFullNameFML(). It seems pretty wild for that to require access to a database! I should be able to define a Contact with only the four fields that affect this method (FirstName, MiddleName, LastName, DisplayMiddleName) and test it.

The fact that Contact (and analogues) are defined as interfaces is a good step for this. But creating implementations of that interface is a pretty big pain (for once, let alone for the hundreds(?) of such interfaces we have).

It's possible that something like Mockito could help. In general, mocks default to returning a sense of "nothing": zero or false for primitives (I don't remember what it does for chars), null for objects. But you can change them as necessary when defining the mock. Maybe I should spend some time pursuing this avenue?