Mocking a database for unittesting

Discussion of open issues, suggestions and bugs regarding SDAC (SQL Server Data Access Components) for Delphi, C++Builder, Lazarus (and FPC)
Post Reply
bravecobra
Posts: 11
Joined: Tue 21 Mar 2006 11:20

Mocking a database for unittesting

Post by bravecobra » Sat 23 Feb 2013 12:39

Hi,

is there a way to mock a database connection/query in unit tests (dunit)?
I'd like to provide (static) results for a TMSQuery/TMSStoredProcedure, without actually connecting to a database. That way I can test my code, without the need of setting up a complete database. The idea is not to test the SQL statements nor the SDAC components, but the code that uses them.
Thus can I have control over the resultset of a TMSQuery, without using a database?

Tnx

AndreyZ

Re: Mocking a database for unittesting

Post by AndreyZ » Mon 25 Feb 2013 11:02

Hello,

If you do not want to connect to the server, you can use the TVirtualTable component, it represents an in-memory data storage. You can find description of the TVirtualTable component in the SDAC documentation. You can find example of using TVirtualTable within SDAC demos. You can find SDAC demos in the SDAC_Install_Directory\Demos directory under Windows XP, and in the "My Documents\Devart\Sdac for you IDE\Demos" directory under Windows Vista/7 (for example, "C:\Documents and Settings\All Users\Documents\Devart\Sdac for your IDE\Demos\", or "C:\Users\Public\Documents\Devart\Sdac for your IDE\Demos\").

bravecobra
Posts: 11
Joined: Tue 21 Mar 2006 11:20

Re: Mocking a database for unittesting

Post by bravecobra » Wed 24 Apr 2013 01:39

Unfortunately, TVirtualTable and TMSQuery don't share the same interface, they only have the same ancestor (TDataset), thus that means it's unusable as a mock.
If I'd be able to talk to something like IMSQuery (exposing TMSQuery functionality) and then use TVirtualTable (implementing the same IMSQuery), then I can easily mock out the resultsets in unittesting.
In production code, I would then use TMSQuery, actually connecting to the database and in the unittests I can test with the static data coming from TVirtualTables. If talking to an interface, the tested code would then never know whether the data comes from the actual database or from TVirtualTables. That's the idea. I currently see no other solution other than writing descendants implementing that common interface.
Is there another solution?

AndreyZ

Re: Mocking a database for unittesting

Post by AndreyZ » Wed 24 Apr 2013 11:18

You can copy all records from one dataset to another using our TCRBatchMove component. TCRBatchMove serves for transferring records between datasets. Here is an example:

Code: Select all

CRBatchMove.Source := MSQuery1;
CRBatchMove.Destination := VirtualTable1;
CRBatchMove.Execute;
You can find detailed description of the TCRBatchMove component in the SDAC documentation.
Using such approach, you can use TVirtualTable in your tests. When you need to test data from the server, you copy data from TMSQuery to TVirtualTable. When you need to test data without connecting to the server, you insert data directly to TVirtualTable. This way, your tests always work with TVirtualTable not knowing where data came from.

bravecobra
Posts: 11
Joined: Tue 21 Mar 2006 11:20

Re: Mocking a database for unittesting

Post by bravecobra » Wed 24 Apr 2013 13:26

I don't think you understand my question. The data itself is irrelevant. I don't want to test the data being returned, neither generate data. I want to test the code that uses a TMSQuery in DUnit, without obviously altering that code. But I don't want my DUnit test to be dependent on an existing database.

AndreyZ

Re: Mocking a database for unittesting

Post by AndreyZ » Wed 24 Apr 2013 15:34

The TMSQuery component cannot be used without an active connection, it is intended to receive data from the server. TVirtualTable represents an in-memory data storage, that is why it can work with data without an active connection.

Post Reply