質問

I am trying to do unit testing with a recent project I have been working on.

It involves a SQL Server 2008 R2 database and a WCF Service using C#, .NET 4.5 and Visual Studio 2013 Premium. We use Entity Framework (EF) 6.0.1.

I am trying to test the WCF in isolation using Microsoft Fakes so that it doesn't require the database. We aim to do this using an "in-memory database". My difficulty is "stubbing" out the dbcontext for EF so I know it is in a known state that can be queried, altered and monitored.

I have read around that this can be bad idea because of the different Linq providers between linq-to-objects vs linq-to-sql. The functionality could pass at compile time but fail at runtime. To combat this we have integration tests as well (connecting the WCF to a real database) once deployed to our DEV servers via TFS.

I have also read around that the dbcontext could be shimmed using MS FAKES but just feels wrong.

Also adding a repository pattern (dependancy injection (DI)) is not causing our code coverage to increase which is one of our desired outcomes.

I then found this article http://msdn.microsoft.com/en-gb/data/dn314429.aspx and this article http://frankdecaire.blogspot.co.uk/2013/11/entity-framework-6-mocking-and-unit.html?showComment=1392224065716

This achieves what I want to do but uses Moq. Can this code be converted from Moq to MS FAKES? Is FAKES capable of doing everything that Moq does or shall I just learn Moq as well to add to my limited knowledge of FAKES?

var mockSet = new Mock<DbSet<account>>();
mockSet.As<IQueryable<account>>().Setup(m => m.Provider)
       .Returns(data.Provider);
mockSet.As<IQueryable<account>>().Setup(m => m.Expression)
       .Returns(data.Expression);
mockSet.As<IQueryable<account>>().Setup(m => m.ElementType)
       .Returns(data.ElementType);
mockSet.As<IQueryable<account>>().Setup(m => m.GetEnumerator())
       .Returns(data.GetEnumerator());

Any questions feel free to ask

Cheers

Kyle

役に立ちましたか?

解決

IMO, you need to start decoupling your code by moving towards a more layered approach. I am not quite sure what you need to achieve by testing WCF in isolation. I suggest having three layers and their tests as below -

  1. Data access - uses EF and its DB context and implements a data access interface. You should unit test this without mocking EF's db context. Tests for this layer would be "state" dependent. By that I mean, your tests will work with real data and database for the CRUD operations. You just need to make sure you do not persist the changes to the db after the test run. One can use Spring.Net's testing library to achieve this or simply run your tests under a transaction scope and roll back the transaction after every test run (in the clean up).

  2. Business logic - contains the business logic and works with the data access interface. Use any DI framework like spring.net or ms unity to inject the data access layer. You should unit test this by trying to avoid actual database calls. This is where something like a NMock, Rhinomock or MOQ comes into picture. Set up boundary and exception conditions using mocks and make sure your business logic addresses all the concerns.

  3. WCF service layer - works with you operation and data contract. Ideally only forwards calls to business logic and translates response to data contract. I prefer having two types of tests at this level: a) unit tests for testing the translation and proper call forwarding. b) few basic integration tests using a proxy and some test data that go through the entire stack without any mocking.

The only problem I have with MS fakes is that it ships with VS2012 ultimate version and hence has a much lesser user base than something like a MOQ.

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top