Mock Repository vs. Real Repository w/Mocked Data - unit-testing

I must be doing something fundamentally wrong.
I am implmenting my repositories and then testing them with mocked data. All is well.
Now I want to test my domain objects so I point them at mock repositories.
But I'm finding that I have to re-implement logic from the 'real' repositories into the mocks, or, create 'helper classes' that encapsulate the logic and interact with the repositories (real or mock), and then I have to test those too.
So what am I missing - why implement and test mock repositories when I could use the real ones with mocked data?
EDIT: To clarify, by 'mocked data' I do not hit the actual database. I have a 'DB mock layer' I can insert under the real repositories that returns known-data.

Maybe your mixing your abstractions. maybe some of the helpers and logic that your talking about should be in your domain objects. Your repositories should be implementing a CRUD interface. So your domain logic should be using 8 actions from the repository. Good retrieve and Bad retrieve (exception thrown) are only two of the eight. One test, is how is the Bad retrieve handled in the domain object. The rest of the tests should be testing a Good retrieve.

Unit testing is meant to minimize the tested element -> test data route, in order to reduce search time if a bug occurs - the bug is either in the routine you test or the test unit and nothing else (well, maybe the OS or the compiler... but these are very rare).
Now imagine you made a database accessor module. The module seems to work ok. Then you make a config reader that reads from the database. Instead of a mock database accessor module unit test, you use your real database module on top of mock config data in the database test unit. It still seems to work OK. Now you add a GUI layer that uses the config object returned by the config reader unit. Instead of mocking the "boiled" config data you use the real module which apparently works.
And now your GUI stops working for a certain value. Where is the error? In the GUI, in the config reader, in the database accessor or in the values in the mock database?
In other words, you're not just testing the code you're writing, you're testing the real repository system as well, and if a bug is found you have an additional layer to analyze.

why implement and test mock
repositories when I could use the real
ones with mocked data?
I guess it really comes down to how much code coverage you think you need to have. If you feel the repository is sound and you can use it for testing, go for it. Perhaps the repository unit tests can be run prior to the mock database unit tests, so that you can use the real repositories for testing and feel confident that the testing is still valid.

Related

Does anybody have experience of using SQLite to write integration tests?

We're using MVC, Entity Framework 4.1 Code First, SQL Server in our project.
Please share your experience: how do you unit test your data service layer? By data service layer I mean services supposed to be run by MVC controllers that have some kind of DbContext derived class declaration inside, so that they depend on this EF DbContext, and encapsulate some business\data logic to fetch and store the data.
After reading few articles and posts, I incline to use separate database to build unit/integration tests on, and I prefer to use in-memory (like SQLite) rather than SQL Compact. However I'm not even sure if it's possible, if you have such an experience, could be please share few lines of code to show how you achieve this.
Unit testing means testing unit = no database, no external dependency, just testing single testable unit. Once you want to involve database you don't unit test any more - you are doing integration testing.
I wrote multiple answers about unit testing / integration testing of code dependent on EF. The last one is here. So if your service layer creates linq queries on context you cannot reliably unit test them. You need integration tests.
I would use the same database as you expect to use in your real code. Why? Because mapping and behaviour between database provides can differ as well as implementation of LINQ. Also in case of SQL server you can use special EF features which don't have to be available in SQLite. Another reason is that last time I checked it, SQLite's provider didn't support database deletion, recreation, etc. which is something people usually want to use for integration tests. Solution for that can be Devart provider.
I don't use a separate database at all. In fact, my Unit Tests don't use a database at all.
My strategy is to create IEnityRepository interfaces for the DB Entities (replace Entity with the actual name). I then pass those to the constructor for my controllers.
During Unit Testing, I simply use a Mocking library to pass mock implementations of the repositories that I need and have the return some set of known data that I can use in the Unit Tests.

EF4.1 DbSet vs. EF4 ObjectContext and Unit Testing

I currently have a project I've started with EF4, and am going back and adding in unit testing after the fact. I am using the EF4 POCO T4 templates with my model (database) first context. I am using generic repositories for my DAC logic, and unit of work pattern for persistence.
However, I'm running into some issues understanding how to mock up the ObjectContext/ObjectSet. I looked at using the FakeObjectSet<T> sample from this article, but it still leaves a few things out, such as auto-incrementing identities and transaction rollbacks.
So, I'm trying to find a good EF design that will still be fully unit testable.
My question is, does EF4.1 DbSet solve a lot of the issues w/ unit testing EF4? Are there any good comprehensive articles for designing EF4.1 solutions that are fully testable?
Also, keep in mind that I need a model-first solution.
Thanks in advance.
Fully simulating behavior of mocked layer is not point of unit testing. The point of unit testing is believing that mocked layer simply works. Unit test verifies the tested method not the mock. You will just verify that correct method on the mock were called and perhaps you will set up some callbacks for modifying passed data if your business logic expects some values. Example:
You have a business method inserting the record to the database and using the entity and its Id after insertion. The IObjectSet mock will be configured to:
Set expectation that AddObject was called only once - you can set the expected instance in the verification
You can define callback for AddObject to set Id to some value and use it later in the test
DbSet will not make any difference - it is just wrapper around ObjectSet with similar behavior. In my opinion there is no efficient way to make mocks behave as real EF. The effort needed for creating mock with behavior simulating EF + database will be much bigger then effort for your whole application! That will not be mock anymore it will be fake EF provider.
If you want to test your EF code (mapping, querying, persisting) and database behavior (like auto-increment, transactions, etc) you have to write integration tests. Here you have some related questions discussing repositories, unit of work and challenges with testing:
ASP.NET MVC3 and Entity Framework Code first architecture
Organizationally, where should I put common queries when using Entity Framework Code First?

Unit testing - testing in isolation

I've got a set up with a number of layers:
Website
Application / Service
Domain (contains entities)
Persistence (contains repositories)
I'm testing the persistence layer in isolation OK using data created in memory from a stub object.
Now, Im thinking about testing my Website layer. I know I should be testing it in isolation which Im thinking means creating a stub for the Application layer object it uses but this stub would need its own set of in memory data, duplicated in the stub in the persistence layer and I dont want to do duplicate this and manage it.
So my question is should the subject under test always work with stub objects from the layer below in order to be isolated and do they normally have their own set of data? Or is OK for my web method under test to call a lightweight object in the Application Layer which calls the Persistence layer with stub data?
Thanks for your help. This feels like the last bit of the puzzle for me ...
Ideally in unit testing each subject under test is isolated from its dependencies. You do not want to think your subject under test is broken because one of its dependencies broke and caused the subject under test to fail. If you test like this, you might spend a lot of time tracking down bugs in the wrong place.
Testing how things operate together is the domain of integration testing, not unit testing
Or is OK for my web method under test to call a lightweight object in the Application Layer which calls the Persistence layer with stub data?
If you do this, I wouldn't call the test a unit test in isolation anymore - if the test fails, where is the bug? - but an integration test. Don't misinterpret me, integration testing is fine too, it just has another purpose. But if your goal is to unit test the website layer in isolation, you should mock/stub direct dependencies.
Setting up test data can be tedious task. If you are using DotNet you can make use of a library called NBuilder to generate test data very easily and quickly. It supports a nice fluent interface. You can read more about it here.

Testing Real Repositories

I've set up unit tests that test a fake repository and tests that make use of a fake repository.
But what about testing the real repository that hits the database ? If this is left to integration tests then it would be seem that it isn't tested directly and problems could be missed.
Am I missing something here?
Well, the integration tests would only test the literal persistence or retrieval of data to and from the layer of persistence. If your repository is doing any kind of logic concerning that data (validation, throwing exceptions if an object isn't found, etc.), that can be unit tested by faking what the persistence layer returns (whether it returns the queried object, a return code, or something else). Your integration test will assure you that the code can physically persist/retrieve data from persistence, and that's it. Any sort of logic to test ought to belong in a unit test.
Sometimes, however, logic could exist in the persistence layer itself (e.g. stored procedures). This could be for the sake of efficiency, or it could merely be legacy code. This is harder to properly unit test, as you can only access the logic by getting to the database. In this scenario, it'd probably be best to try and move the logic to your code base as much as possible, so that it can be tested more easily. There probably exist unit testing frameworks for scenarios such as these, but I'm not aware of them (merely out of inexperience).
Can you set up a real repository that tests against a fake database?
Regardless of what you do, this is integration testing, not unit testing.
I'd definitely suggest integration tests against the DAL, within reason.
We don't use the Repository pattern per se (to our chagrin), but our policy for similar classes (Searchers) is as follows:
If the method does a simple retrieve from the database using an O/RM call, don't test it.
If the method uses query-building features of the O/RM, test it.
If the method contains a string (such as a column name), test it.
If the method calls a stored procedure, test it.
If the method contains logic, test it. But try to avoid logic.
If the method bypasses the O/RM and uses raw SQL, test it. But really try to avoid this.
The gist is you should know your O/RM works (and hopefully has tests), so there's no reason to test basic CRUD behavior.
You'll definitely want a "test deck" - an in-memory database, a local file-backed database that can be checked into source control, or (if you have to) a shared database. Some testing frameworks offer rollback facilities to restore the database state; just be careful if you're hitting multiple databases in the same test or (in some cases) if you have embedded transactions.
EDIT: Note that these integration tests will still test your repository in "isolation" (save for the database). All your other unit tests will use a fake repository.
I recently covered a very similar question over here.
In summary: test your concrete Repository implementations if there's value in doing so. If you are doing something complex in your implementation, it is probably a good idea to test it. If you are using an ORM with no custom logic, there may not be much value in writing tests at that level.

Which object should I mock?

I am writing a repository. Fetching objects is done through a DAO. Creating and updating objects is done through a Request object, which is given to a RequestHandler object (a la Command pattern). I didn't write the DAO, Request, or RequestHandler, so I can't modify them.
I'm trying to write a test for this repository. I have mocked out both the DAO and RequestHandler. My goal is to have the mocked RequestHandler simply add the new or updated object to the mocked DAO. This will create the illusion that I'm talking to the DB. This way, I don't have to mock the repository for all the classes that call this repository.
The problem is that the Request object is this gob of string blobs and various alphanumeric codes. I'm pretty sure XML is involved too. It's sort of a mess. Another developer is writing the code to create the Request object based on the objects being stored. And since RequestHandler takes in Requests and not the object I'm storing, it can't update the mocked DAO.
So the question is: do I mock the Request too, or should I wait until the other guy, who is kind of slow, to finish his code before I write the test? Or screw it and mock out the entire repository when testing the classes that call the repository?
BTW, I say "mock" not in the NMock sense, but rather like faking the DB with an in-memory collection.
To test the repository I would suggest that you use test doubles for all of the lower layer objects.
To test the classes that depend on the repository I would suggest that you use test doubles for the repository.
In both cases I mean test doubles created by some mocking library (fakes where that works for the test, stubs where you need to return something to the object under test and mocks if you really have to).
If you are creating an implementation of the DAO using in-memory collections to functionally replace the database in a demo or test system that is different to unit testing the upper layers. I have done something similar so that I can give prototypes to people and concentrate on business objects not the physical model. That isn't for unit testing though.
You may of may not be creating a web application, but you can have a look at the NerdDinner application which uses Repository. It is a free PDF that explains how to create an application using ASP.NET MVC and can be found here: Professional ASP.NET MVC 2.0