开发者

ASP.NET MVC Unit Tests - Fake repository has become unwieldy

Things started off simple with my fake repositories that contained hard-coded lists of entities.

As I have progressed, my shared fake repositories have become bloated. I am continually adding new properties and new entities to these lists. This is making it extremely difficult to maintain and it is also difficult to see what the test is doing. I believe this is an anti-pattern called "General Fixture".

In researching ASP.NET MVC unit tests, I have seen two methods for preparing repository fixtures that are passed on to the controllers.

  1. Create hard-coded fake repositories that are shared among all tests
  2. Mock parts of the repositories within each test

I'm tempted to explore option #2 above but I've read t开发者_如何学Gohat it's not a good idea to mock repositories and it seems quite daunting in the scenarios where I'm testing a controller that operates on collections (i.e. with paging/sorting/filtering capabilities).

My question to the community...

What methods for preparing repository fixtures work well beyond rudimentary examples?


I dont think you should only be choosing one of the two options. There are cases when using a fake repository would be better, and there are cases when mocking would be better. I think you should assess what you need on a case by case basis. For example, if you are writing a test for a UsersService that needs to call an IUserRepository.DoesUserExist() that returns a boolean, then you wouldnt use a fake repository, its easier just to Mock a call to return true or false.

Moq is awesome.


For a similar reason on a new project I'm looking into using an ORM (NHibernate in my case). That way I can point it at an "in-memory" SQLLite instance (rather than SQL Server) and it should be far easier to set up / maintain (I hope). That way I will only need to mock the repository if I have a requirement to test particular scenarios (such as time-outs, etc)


If you are using your Unit Tests for TDD, download Rhino Mocks and use optione #2.


For the most part, we go with test specific repository mocks. I've never seen advice not to do this myself and I find that it works great. For the most part, our repository methods and therefore our mocks only return single models or lists of models (not data contexts) so it is easy to create the data specific for each test and isolated to each query. This means that we can mock whatever data we like without affecting other tests or queries in the same test. It is very easy to see why the data was created and what it is testing.

I have been on teams have also decided to create shared mock data from time to time as well. I think the decision was generally made because the routines generated dynamic queries and the data required to mock all of the tests resulted in a good portion of the database being duplicated. However, in retrospect, I probably would have suggested that only the resulting queries need to be checked, not the contents returned from the database. And thus, no data at all would be mocked though, it would have required some code changes. I only mention this to illustrate that if you can't see to find a way to make option 2 work, maybe there is a way to refactor the code to make it more testable.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜