2

I have been watching various videos and reading various blogs where they go about unit testing a repository.

The most common pattern is to create a Fake repository that implements the same interface as the real one. Then the fake one uses an internal Dictionary or something.

So in effect you are unit testing the logic of the fakerepository which will never go into production.

Now you may use dependency injection to inject a mock DBContext by using some IDBContext interface. However then you are just testing each repository method which in effect just forward to the dbcontext (which is mocked).

So unless each repository method has lots of logic before calling on the dbcontext then it seems a bit pointless?

I think it would be better to have the tests on repository as integration tests and actually have them hitting the Database?

The new EF 4.1 makes this easy as it can create the database on the fly based on a connection string in your test project, then you can delete it after tests are run using the dbcontext.Database methods.

razlebe
  • 7,134
  • 6
  • 42
  • 57
Mark
  • 1,538
  • 5
  • 24
  • 31

2 Answers2

4

Your objections are partially correct. Their correctness depends on the way how the repository is defined.

  • First faking or mocking repository is not for testing repository itself but for testing layers using the repository.
  • If the repository exposes IQueryable and upper layer can build linq-to-entities query then mocking repository means testing non existing logic. You need integration test and run the query against a real testing database. You can either redeploy database for each test which will make it very slow or you can run each test in a transaction and rollback it when the test completes.
  • If the repository doesn't exposes IQueryable you can still think about it as a black box and mock it. Query logic will be inside the repository and it will be tested separately with integration tests.

I would refer you to set of other answers about repository itself and testing.

Community
  • 1
  • 1
Ladislav Mrnka
  • 360,892
  • 59
  • 660
  • 670
0

The best approach I have seen is from Sharp Architecture where they use a SQLLite database, created in the TestFixtureSetup based on the NHibernate mapping info.

The repository tests then use this In-Memory database.

Technically this is still integration test as database involved, but practically, it ticks all the boxes for a unit test since:

1) The database is transient - no connection string configs to worry about, nor do you need a complete db sitting on a server somewhere for the unit test to use.

2) The setup is fast, and the tests equally so as all in memory.

3) As it uses the NHibernate mapping info to generate the schema, you don't have to worry about keeping the unit test setup synchronised with code changes.

http://wiki.sharparchitecture.net/default.aspx?AspxAutoDetectCookieSupport=1

It may be possible to use the same approach with EF.

BonyT
  • 10,750
  • 5
  • 31
  • 52
  • Sounds interesting but again its testing something that wont go into production. I prefer to create a database on the fly for the tests locally or on the build server, this is easily done using EF 4.1 – Mark Jul 01 '11 at 12:39
  • Well many unit tests, test things that won't go into production. Any time you have a FixtureSetup process, you introduce something that is a mock of the live system's behaviour. However, on balance I agree - I have not yet found tests of this nature to be worth the effort of setup. – BonyT Jul 01 '11 at 12:46