开发者

Using repository pattern in ASP.NET MVC with a SQL Server DB; how to mock repository so its unit testable without breaking OOD

I've been learning the ASP.NET MVC framework using th开发者_如何学运维e Apress book "Pro ASP.NET MVC Framework" by Steven Sanderson. To that end I have been trying out a few things on a project that I am not that familar with but are things that I thing I should be doing, namely:

  • Using repository pattern to access my database and populate my domain/business objects.
  • Use an interface for the repository so it can be mocked in a test project.
  • Use inversion of control to create my controllers

I have an MVC web app, domain library, test library.

In my database my domain items have an Id represented as an int identity column. In my domain classes the setter is internal so only the repository can set it.

So my quandries/problems are:

  1. Effectively all classes in the domain library can set the Id property, not good for OOP as they should be read-only.
  2. In my test library I create a fake repository. However since it's a different assembly I can't set the Id properties on classes.

What do others do when using a database data store? I imagine that many use an integer Id as unique identifier in the database and would then need to set it the object but not by anything else.


Can't you set your objects' IDs during construction and make them read-only, rather than setting IDs through a setter method?

Or do you need to set the ID at other times. If that's the case, could you explain why?

EDIT:

Would it be possible to divorce the ID and the domain object? Does anything other than the repository need to know the ID?

Remove the ID field from your domain object, and have your repository implementations track object IDs using a private Dictionary. That way anyone can create instances of your domain objects, but they can't do silly things with the IDs.

That way, the IDs of the domain objects are whatever the repository implementation decides they are - they could be ints from a database, urls, or file names.

If someone creates a new domain object outside of the repository and say, tried to save it to your repository, you can look up the ID of the object and save it as appropriate. If the ID isn't there, you can either throw an exception to say you need to create the object using a repository method, or create a new ID for it.

Is there anything that would stop you from using this pattern?


you can use the InternalsVisibleTo attribute. It will allow the types from an assembly to be visible from the tests (provided they are in different assemblies).

Otherwise you can leave the property read-only for the external objects but in the same time have a constructor which has an ID parameter and sets the ID property. Then you can call that constructor.

Hope this helps.

0

上一篇:

下一篇:

精彩评论

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

最新问答

问答排行榜