How to test Repository Pattern with ADO.NET Entity Framework? - c#

While using Repository pattern I find it difficult to understand the reason of designing the software with TDD technique while in reality you will have to implement the Interface for your repository in your persistence dataset.
To make my point clear I will submit an example:
I have the following Interface on my domain model:
public interface IUserRepository
{
IQueryable<User> FindAllUsers();
void AddUser(User newUser);
User GetUserByID(int userID);
void Update(User userToUpdate);
}
I have the following implementation of the interface for testing purposes:
public class FakeUserRepository : IUserRepository
{
private IList<User> _repository;
public FakeUserRepository()
{
_repository = new List<User>();
... //create all users for testing purposes
}
public IQueryable<User> FindAllUsers()
{
return _repository.AsQueryable<User>(); //returns all users
}
Now I create a few tests:
Can_Add_User
Can_Add_Account for a User
Can_Add_ShareSpace for a an account of a user with another user.
My question is, after I test all these with my FakeUserRepository implementation, I have to go back and implement the IUserRepository on my actual persistence dataset (i.g. SQL), and I have to implement again the code, so my unit testing is not actually checking the code that I am actually using on my application.
Maybe I am missing something.
Thanks as always!
Below then my Persistent data access repository which is the one that is supposed to be under test (by my mind at least), but then I should not test hooked to the database:
public class SQLUserRepository : IUserRepository
{
private BusinessDomainModel.EntityModel.BusinessHelperAccountDBEntities _repository;
public SQLUserRepository()
{
_repository = new BusinessHelperAccountDBEntities();
}
#region IUserRepository Members
public IQueryable<User> FindAllUsers()
{
return _repository.UserSet.AsQueryable();
}

Never test a mock. The class under test should always be a real instance of the class, though you can and should mock any of its dependencies so you can test it in isolation.

I'll explain what I'm doing, why and how much milage I get out it.
First, I'm doing exactly what you are doing, regarding your repositories. Despite some namespace differences, this is what I also do:
MyProject.Repositories.IUserRepository
MyProject.Repositories.Fake.UserRepository
MyProject.Repositories.SqlServer.UserRepository
With my fake UserRepository, I also just create and populate a private IEnumerable<User> collection (which is a List<User>). Why do I have this? I use this repository for my initial day to day development (because it's fast -> no db access == quick!). Then i swap over the fake respitories for the sql repositories (ie chage my dependency injection (oooohhh!)). This is why this class/namespace exists, as opposed to using Mocks in my unit test for 'fake' stuff. (That happens, but under different circumstances).
With my sql server UserRepository, I use LinqToSql. With regards to you question, it's irrelivant that I'm using LinqToSql ... it could be any other database wrapper. The important thing here is that there's a 3rd party something which i'm integrating with.
Ok, so from here, I need to make sure of two things
The fake UserRepostiory works
The sql server UserRepository works.
First up, most people don't create a unit test for a fake thing. It's a fake piece of turd, so why waste the energy? True --- except that I use that fake piece of turd in my day to day development (refer to my blarg about this, above). So i quickly whip up a few basic unit tests. NOTE: In my eyes these are unit tests, even though they are repository classes. Why? They aren't intergrating with a 3rd party/infrastructure.
Next (finally I get to the point), I do a seperate test class which is an Intergration Test. This is a unit test that will intergrate with something outside of the system. It could be the real Twitter api. It could be the real S3 Amazon api. Notice i used the word real. That's the key, here. I'm intergrating with a real service OUTSIDE of mine. As such -> it's slow. Anytime i need to leave my computer for some data, it's called intergrating and you automatically assume (and expect) it to be slow.
So here, i'm intergrating with a Database.
(Nae sayers, please don't Troll this with cheeky suggestions that you have the database on the same computer ... you're leaving your APPLICATION 'world').
Wow. this is some War-n-Peace novel .. time for some hard action, cock slappin code.
Lets bring it!
namespace MyProject.Tests.Repositories.SqlServer
{
// ReSharper disable InconsistentNaming
[TestClass]
public class UserRepositoryTests : TestBase
{
[ClassInitialize]
public static void ClassInitialize(TestContext testContext)
{
// Arrange.
// NOTE: this method is inherited from the TestBase abstract class.
// Eg. protected IUserRepository =
// new MyProject.Respositories.SqlServer
// .UserRespository(connectionString);
InitializeSqlServerTestData();
}
[TestMethod]
public void GetFirst20UsersSuccess()
{
// Act.
var users = _users.GetUsers()
.Take(20)
.ToList();
// Assert.
Assert.IsNotNull(users);
Assert.IsTrue(users.Count() > 0);
}
}
}
Ok, lets run through this puppy.
First up, this is using Microsoft Unit Testing - built into VS2010 Beta2 or with the Team Foundation edition of VS2008 (or whatever that version is ... i just install the copy our work has purchased).
Second, whenever the class is first initialized (be it one test or many), it creates the context. In my case, my Sql Server UserRepository which will use a LinqToSql context. (Yours will be an EF context). This is the Arrange part of TDD.
Third, i call the method -> this is the Act part of TDD.
Last, I check if i got back what i expected -> this is the Assert part of TDD.
What about updating the DB?
Just follow the same pattern except you might want to wrap your calling code in a transaction and the roll it back. Otherwise u might get 100's of rows of data which could possibly be the same. Downside to this? Any identity fields will not have all nice and pretty numbering sequence (becuase the rollback will 'use' that number). Doesn't make sence? don't worry. that's an advanced tip i thought i'd throw in to test you out, but it means diddly squat for this hellishly long post.
so .. er.. yeah. that's what i do. Don't know if the Gods of Programming, on these forums, will flip and throw mud my way but I sorta like it and I'm hoping it might help ya.
HTH.

You should test the real class not a fake one you make for testing. The point of using an interface is that it allows you to mock out the class, so you can use the mock version in tests with other collaborators.
In order to test the class you should be able to pass in a mock database and assert that the calls you expected to be made in to the database actually happen when you call the methods on your Repository class.
Here is a good intro to mocking and testing in C#:
http://refact.blogspot.com/2007/01/mock-objects-and-rhino.html

Related

Why inject the entire DbContext instead of just the necessary DbSets?

I've seen a lot of projects whether the entire DbContext is injected in a class:
public class MyClass
{
public MyClass(MyDbContext context)
{
...
}
public void DoStuff()
{
dbContext.MyTable.Select(x => x...)
}
}
Why not do this:
public class MyClass
{
public MyClass(DbSet<MyType> myTypes)
{
...
}
public void DoStuff()
{
myTypes.Select(x => x...)
}
}
I find #2 makes it more clear as to what data exactly the object needs to operate. It makes unit testing especially more clear as the dependencies are obvious from the constructor. Otherwise, you have to inspect the implementation of the method to find out what data it needs exactly so you can setup your test properly.
So why is #1 the norm?
(P.S. sorry for bad tags but it seems the tag system is broken atm)
Normally developers write unit tests to test business use cases and the data access layer should not contain any logic and that's why people use Repository Pattern to hide the implementation of the data access layer.
Otherwise, you have to inspect the implementation of the method to
find out what data it needs exactly so you can setup your test
properly.
MyDbContext and DbSet<MyType> are related to data access and when you try to implement unit tests for DoStuff method, you should not consider the implementation of query for writing test and the only thing you need is mocking MyDbContext or DbSet<MyType>. Also when use concrete class as a dependency, you violate Dependency Inversion Principle, and that is why you have to look at the implementation of DoStuff method to find out what data and where the data comes from.
Because the "Save" is on the dbcontext, not the child collections.
"SaveChangesAsync" as the most important one. But others listed below.
int saveChangesAsyncValue = await this.myDbContext.SaveChangesAsync(token);
Framework:
https://learn.microsoft.com/en-us/dotnet/api/system.data.entity.dbcontext.savechangesasync?view=entity-framework-6.2.0
Core:
https://learn.microsoft.com/en-us/dotnet/api/microsoft.entityframeworkcore.dbcontext.savechangesasync?view=efcore-5.0
Others (core):
https://learn.microsoft.com/en-us/dotnet/api/microsoft.entityframeworkcore.dbcontext.savechanges?view=efcore-5.0
You should really focus having unit tests on your BUSINESS LOGIC. And subtly, this also means.
Stop putting (any) business logic in your data layer. (and its kissing cousin, stop putting business logic in your presentation layer).
You should inject a (mock) of your datalayer into your business logic classes.
Having said that, EF InMemoryDatabase has blurred the lines a little bit.
But that does not avoid having to have the "myDbContext" available.

What should you do about nested ViewModels when you are unit testing?

I was working on creating some unit tests for my ViewModels in my project. I didn't really have a problem as most of them were very simple, but ran into an issue when I had a new (unfinished) ViewModel inside of my other ViewModel.
public class OrderViewModel : ViewModelBase
{
public OrderViewModel(IDataService dataService, int orderId)
{
\\ ...
Payments = new ObservableCollection<PaymentViewModel>();
}
public ObservableCollection<PaymentViewModel> Payments { get; private set; }
public OrderStatus Status { ... } //INPC
public void AddPayment()
{
var vm = new PaymentViewModel();
payments.Add(vm);
// TODO: Subscribe to PaymentViewModel.OnPropertyChanged so that
// if the payment is valid, we update the Status to ready.
}
}
I want to create a unit test so that if any of my PaymentViewModel's IsValid property changes and all of them are true that Status should be OrderStatus.Ready. I can implement the class, but what gets me worried is that my unit test will break if the problem is in PaymentViewModel.
I'm not sure if this is OK or not, but it just feels like I should not have to worry about whether or not PaymentViewModel operates properly in order for my unit test for OrderViewModel is correct.
public void GivenPaymentIsValidChangesAndAllPaymentsAreValid_ThenStatusIsReady()
{
var vm = new OrderViewModel();
vm.AddPayment();
vm.AddPayment();
foreach (var payment in vm.Payments)
{
Assert.AreNotEqual(vm.Status, OrderStatus.Ready);
MakePaymentValid(payment);
}
// Now all payments should be valid, so the order status should be ready.
Assert.AreEqual(vm.Status, OrderStatus.Ready);
}
The problem is, how do I write MakePaymentValid in such a way that I guarantee that the PaymentViewModel's behavior will not negatively impact my unit test? Because if it does, then my unit test will fail based on another piece of code not working, rather than my code. Or, should it fail if PaymentViewModel is wrong as well? I am just torn in that I don't think that my tests for OrderViewModel should fail if PaymentViewModel has a bug.
I realize that I could always create an interface like how I do with IDataService, but it seems to me that that is a bit of an overkill to have every single ViewModel have an interface and injected in some how?
When it comes to unit testing you absolutely should separate out your tests from any external dependencies. Keep in mind that this does not mean you must pass in some interface; you will run into situations where you have a specific class being utilized, whether that class is in or out of your control.
Imagine that instead of your example, you were relying on DateTime.Now. Some would argue to abstract it away into some sort of interface IDateTimeService, which could work. Alternatively, you could take advantage of Microsoft Fakes: Shims & Stubs.
Microsoft Fakes will allow you to create Shim* instances. There is a lot to go over on this subject, but the image Microsoft provides illustrates that the usage of Fakes goes beyond classes out of your control (it includes components within your control as well).
Notice how the component you are testing (OrderViewModel) should be isolated from System.dll (i.e. DateTime.Now), other components (PaymentViewModel), and external items as well (if you relied on a Database or Web Service). The Shim is for faking classes, whereas the Stub is for faking (mocking) interfaces.
Once you add a Fakes assembly, simply use the ShimPaymentViewModel class to provide the behavior you expect that it should. If, for whatever reason, the real PaymentViewModel class misbehaves and your application crashes you can at least be assured that the problem was not due to the OrderViewModel. Of course, to avoid that you should include some unit tests for PaymentViewModel to ensure that it behaves properly regardless of what other classes are utilizing it or how they are utilizing it.
TL;DR;
Yes, completely isolate your component when it comes to testing by taking advantage of Microsoft Fakes. Oh, and Microsoft Fakes does play nicely with other frameworks, so don't feel like that by using it that you are foregoing other options; it works in conjunction with other frameworks.

Unit test a method which is on high abstraction level

A similar topic has been discussed in The value of high level unit tests and mock objects
However, I'd like to describe a specific situation and ask your opinion about how I should write a unit test.
I am developing an ordinary 3-tier application, which uses Entity Framework. Above EF, I have two layers:
Repositories: They directly access the EF ObjectContext and do all the CRUD work (actually, these classes are generated with a T4 template). All Repository class has an appropriate interface.
Managers: They implement the higher level business logic, they do not access directly the ObjectContext, rather use an appropriate Repository. Managers do not know the concrete Repository-implementation, only the interface (I use dependency injection, and mocks in the unit test).
Without further description, here is the class I'd like to write unit tests for:
public class PersonManager
{
private IPersonRepository personRepository; // This is injected.
// Constructor for injection is here.
public void ComplexMethod()
{
// High level business logic
bool result = this.SimpleMethod1();
if(result)
this.SimpleMethod2(1);
else
this.SimpleMethod2(2);
}
public bool SimpleMethod1()
{
// Doing some low-level work with the repository.
}
public void SimpleMethod2(int param)
{
// Doing some low-level work with the repository.
}
}
It is really easy to unit test SimpleMethod1 and SimpleMethod2 by instantiating the PersonManager with a mock of the PersonRepository.
But I can not find any convenient way to unit test ComplexMethod.
Do you have any recommendation about how should I do that? Or that should not be unit tested at all? Maybe I should not use the this reference for the method calls in ComplexMethod, rather access the PersonManager itself via an interface, and replace that with a mock too?
Thanks in advance for any advice.
Guillaume's answer is good (+1), but I wanted to give an additional observation. What I see in the code you've posted is the basis for a very common question from people trying to figure out (or argue against) TDD, which is:
"How/why should I test ComplexMethod() since it depends on SimpleMethod1() and SimpleMethod2(), which are already tested and have their own behavior that I'd have to account for in tests of ComplexMethod()? I'd have to basically duplicate all the tests of SimpleMethod1() and SimpleMethod2() in order to fully test ComplexMethod(), and that's just stupid."
Shortly after, they usually find out about partial mocks. Using partial mocks, you could mock SimpleMethod1() and SimpleMethod2() and then test ComplexMethod() using normal mock mechanisms. "Sounds great," they think, "This will solve my problem perfectly!". A good mock framework should strongly discourage using partial mocks in this way, though, because the reality is:
Your tests are telling you about a design problem.
Specifically, they're telling you that you've mixed concerns and/or abstraction levels in one class. They're telling you that SimpleMethod1() and SimpleMethod2() should be extracted to another class which this class depends on. No matter how many times I see this scenario, and no matter how vehemently the developer argues, the tests are proven right in the end 100% of the time.
I don't see what the problem is. You can test your complex method while mocking the repository, there is no problem.
Your would need two unit-tests, each one would use the same sequence of expectations and executions that you have in your tests of the SimpleMethod1 (I assume you already have two unit-tests for SimpleMethod1, one for a return of "true", one for "false") and also the same expectations that you have for your test SimpleMethod2 with a fixed parameter 1, or 2 respectively.
Granted, there would be some "duplication" in your testing class, but that's not a problem.
Also note your tests for SimpleMethod2 should not make any assumption for the parameter passed: in "real-life" you can have only 1 or 2 as a parameter (and that's what your unit-test for ComplexMethod would have), but your unit-tests for SImpleMethod2 should test it whatever the parameter is: any int.
And finally, if ComplexMethod is the ONLY way to call SimpleMethod1 and/or SimpleMethod2, you should consider making these private, and have only unit-tests for ComplexMethod.
Does that make sense?

Is Typemock the only framework that can mock a Linq To SQL Table class?

I am trying to setup unit tests for my Linq To SQL code. My code uses the System.Data.Linq.Table class (generated by the designer).
Because this class is sealed and the constructor is internal it is completely impervious to unit testing frameworks like Rhino Mocks. (Unless you want to alter you code to use the repository pattern, which I would rather not.)
Typemock can (some how) mock this class. (See here for an example.)
However, Typemock is also $800 a license. I don't see my employer springing for that anytime soon.
So here is the question. Are there any other mocking frameworks out there that don't rely on Interfaces to create the mocks?
Edit: Example of code that I need to test:
public class UserDAL : IUserDAL
{
private IDataClassesDataContext _ctx;
public UserDAL()
{
string env = ConfigurationManager.AppSettings["Environment"];
string connectionString = ConfigurationManager
.ConnectionStrings[env].ConnectionString;
_ctx = new DataClassesDataContext(connectionString);
}
public UserDAL(IDataClassesDataContext context)
{
_ctx = context;
}
public List<User> GetUsersByOrganization(int organizationId)
{
IOrderedQueryable<User> vUsers =
(from myUsers in _ctx.Users
where myUsers.Organization == organizationId
orderby myUsers.LastName
select myUsers);
return vUsers.ToList();
}
public bool IsUserInOrganization(User user, int orgainzationID)
{
// Do some Dal Related logic here.
return GetUsersByOrganization(orgainzationID).Contains(user);
}
}
I have shorted this up to make it easier to read. The idea is that I have some code (like IsUserInOrganization that calls another method (like GetUsersByOrganization) that does a Linq query.
I would like to unit test the IsUserInOrganization method. Do do that I would need to mock _ctx.Users which is a Table class (that is sealed and has an internal constructor).
Check out Microsoft Stubs that has the simple premise of:
Replace any .NET method with your own
delegate!
And a more detailed description of it's capabilities (emphasis is mine).
Stubs is a lightweight framework for
test stubs and detours in .NET that is
entirely based on delegates, type
safe, refactorable and source code
generated. Stubs was designed provide
a minimal overhead to the Pex white
box analysis, support the Code
Contracts runtime writer and
encourage the programmatic models
rather than record/replay tests.
Stubs may be used on any .NET method, including non-virtual/static
methods in sealed types.
There are two standard unit testing approaches in this case:
1) Don't test the platform - if the dependency is on a framework class, you don't write tests where that interaction is verified. This typically means you substitute a dependency at test time, but in your case it likely means you inject the table itself.
2) Wrap the platform - if you need to test something that interacts with the platform, then write a wrapper layer for the relevant components
There's also integration and acceptance testing to consider. For both of these cases you would usually simply accept the dependency as it exists in your application.
What precisely are you concerned about testing that you need to directly mock/substitute this class?
Edit:
It seems as if you're looking to avoid rewriting code to be more testable. This is where TypeMock excels, and is the reason why some test advocates think TypeMock can lead to problems. It is, however, the right tool for the job if you absolutely refuse to restructure your code for testability.
Edit #2:
Perhaps I'm being overly obsessive about this, but let's consider a more testable pattern:
Organization()
{
HasUser(name)
}
OrganizationDAL
{
Organization LoadOrganization(id)
}
OrganizationServiceFacade
{
IsUserInOrganization(name, orgid)
{
return OrgDAL.LoadOrganization(id).HasUser(name)
}
}
Organization's natural contains test for a user no longer needs to be platform-dependent, you should be able to inject the datasource. OrganizationDAL is only responsible for loading organizations rather than returning information about organizations (although there are ways to put queries into this layer if necessary). OrganizationServiceFacade is only responsible for providing composed services, which should both satisfy mockability and avoid the need for extra unit tests (it's an Integration or possibly even an Acceptance target) since it's a wrapper class. Depending on how you construct Organizations, you can inject data without relying on a particular notion of how that data works.
You may want to consider using the Repository pattern, basically it's the "wrap the platform" suggestion from Mike. With it you'll be mocking IRepository rather then the DataContext.
http://blogs.microsoft.co.il/blogs/kim/archive/2008/11/14/testable-data-access-with-the-repository-pattern.aspx

NUnit testing the application, not the environment or database

I want to be better at using NUnit for testing the applications I write, but I often find that the unit tests I write have a direct link to the environment or underlying database on the development machine instead.
Let me make an example.
I'm writing a class which has the single responsibility of retriving a string, which has been stored in the registry by another application. The key is stored in HKCU\Software\CustomApplication\IniPath.
The Test I end up writing looks like this;
[Test]
public void GetIniDir()
{
RegistryReader r = new RegistryReader();
Assert.AreEqual(#"C:\Programfiles\CustomApplication\SomeDir", r.IniDir);
}
But the problem here is that the string #"C:\Programfiles\CustomApplication\SomeDir" is really just correct right now. Tomorrow it might have changed to #"C:\Anotherdir\SomeDir", and suddenly that breaks my unit tests, even though the code hasn't changed.
This problem is also seen when I create a class which does CRUD operations against a database. The data in the database can change all the time, and this in turn makes the tests fail. So even if my class does what it is intended to do it will fail because the database returns more customers that it had when I originally wrote the test.
[Test]
public void GetAllCustomersCount()
{
DAL d = new DAL();
Assert.AreEqual(249, d.GetCustomerCount());
}
Do you guys have any tips on writing Tests which do not rely on the surrounding environment as much?
The solution to this problem is well-known: mocking. Refactor your code to interfaces, then develop fake classes to implement those interfaces or mock them with a mocking framework, such as RhinoMocks, easyMock, Moq, et. al. Using fake or mock classes allow you to define what the interface returns for your test without having to actually interact with the external entity, such as a database.
For more info on mocking via SO, try this Google search: http://www.google.com/search?q=mock+site:stackoverflow.com. You may also be interesting in the definitions at: What's the difference between faking, mocking, and stubbing?
Additionally, good development practices, such as dependency injection (as #Patrik suggests), which allows the decoupling of your classes from its dependencies, and the avoidance of static objects, which makes unit testing harder, will facilitate your testing. Using TDD practices -- where the tests are developed first -- will help you to naturally develop applications that incorporate these design principles.
The easiest way is to make the dependencies explicit using dependency injection. For example, your first example has a dependency on the registry, make this dependency explicit by passing an IRegistry (an interface that you'll define) instance and then only use this passed in dependency to read from the registry. This way you can pass in an IRegistry-stub when testing that always return a known value, in production you instead use an implementation that actually reads from the registry.
public interface IRegistry
{
string GetCurrentUserValue(string key);
}
public class RegistryReader
{
public RegistryReader(IRegistry registry)
{
...
// make the dependency explicit in the constructor.
}
}
[TestFixture]
public class RegistryReaderTests
{
[Test]
public void Foo_test()
{
var stub = new StubRegistry();
stub.ReturnValue = "known value";
RegistryReader testedReader = new RegistryReader(stub);
// test here...
}
public class StubRegistry
: IRegistry
{
public string ReturnValue;
public string GetCurrentUserValue(string key)
{
return ReturnValue;
}
}
}
In this quick example i use manual stubbing, of course you could use any mocking framework for this.
Other way is to create separate database for tests.
You should read up on the inversion of control principle and how to use the dependency injection technique - that really helps you write testable code.
In your case, you should probably have an interface - e.g. IIniDirProvider - which is implemented by RegistryBasedIniDirProvider, which is resposible for providing the initial directory based off a specific key in the registry.
Then, when some other class needs to look up the initial directory, that other class should have the following ctor:
public SomeOtherClass(IIniDirProvider iniDirProvider)
{
this.iniDirProvider = iniDirProvider;
}
-allowing you to pass in a mock IIniDirProvider when you need to unit test SomeOtherClass. That way your unit test will not depend on anything being present in the registry.

Categories