Answer the question
In order to leave comments, you need to log in
Testing a wrapper for a database
The development of a solution for the EDMS DocsVision has been underway for a long time. Part of the code is covered with tests, at a certain moment there was a desire to stop, refactor everything that has already been written and cover maximum logic with tests.
The problem is breaking the dependency from the database. Now the interaction with the database looks like this - we get an object of the CardData type (containing a dictionary of all data from different tables that make up the Card object) and pass it to the generated wrapper class, which provides all the data as its property, using CardData as a low-level object to access the database.
The structure of the database is a "black box" and is not documented.
The question is what is the best way to get away from the connection with the database in tests? Extract the interface of each wrapper class, create mock objects based on it and use real objects in real code, and fake ones in the call through tests? Or maybe something easier?
And, where to get the data for the objects - fill it in manually in the constructors for tests or what?
And is it so bad to use real objects when testing in this case - when the database structure is not documented?
Answer the question
In order to leave comments, you need to log in
I am also interested in this issue, but have not yet seen particularly interesting solutions. It feels like a well-tested database connection is ActiveRecord. Or, more flexible, but with the same disadvantages, a query builder (a la, for PHP, $db->select()->where()->...).
The main problem is the loss of flexibility and efficiency: all recording and sampling options have to be reduced to those that are understood by the base classes, and which, accordingly, are tested. Those. it will not be possible to use extended DBMS features for individual cases if they are not embedded in class methods (FORCE INDEX? subqueries?). ActiveRecord, in the case of PHP, also turns out to be overhead for the processor and memory.
There is, of course, an option to implement standard methods in base classes, and for special cases, define them in classes of specific objects and test them already there.
A selection from several tables, it seems to me, is not a fundamental obstacle for ActiveRecord, since you can define standard tools for this in your code.
Another option, how to develop a query builder, is your own query language, like the one in Doctrine. I didn’t get to use it, but I can assume that you can consistently put more and more functionality into your language / constructor, infinitely bringing it closer to SQL (and, accordingly, the ideal is a parser of the desired SQL dialect that is completely covered with tests, translating queries into methods programming language).
I don't know how it is in .net with its own query languages. I heard that there is something called LINQ for this.
For reasons of a pragmatic (slow and voluminous) and personal (why do I need this hemorrhoids) nature, I don’t use either ActiveRecord or constructors / query languages in current very loaded projects, and I haven’t seen any other solutions. Therefore, it remains only to test specific models, duplicating methods with execution in memory.
To be honest, this has not yet been implemented, and models crawl into the database even in tests. In order for the tests to run in a reasonable time, there is a desire to raise the database in memory, and since I don’t count on the support of proprietary MySQL extensions in any HSQLDB, it will be MySQL on tmpfs.
Regarding “where to get data for objects - fill it in manually in constructors for tests or what?”
The base can be hammered in automatically, generating objects / records with any adequate data. Strings can be generated either simply randomly, or according to a dictionary, or by libraries for generating pseudo-meaningful strings (it seems that such a one has recently flown in q&a).
Another thing is that in tests you need to test the behavior of the code under certain conditions, which means that you need to put what you will be testing directly into the base. Subject to boundary conditions, error handling, etc. Therefore, you must either manually write down what should get into the database before the test, or, if the test needs a large amount of data, generate it in advance and transfer it, for example, from the prepared xml / json to the test database.
Didn't find what you were looking for?
Ask your questionAsk a Question
731 491 924 answers to any question