fake DataRepository - emulating the database - c#

Quick Info: I'm using C# 4.0 and RhinoMocks (with AAA)
I'll explain with some code what I'm thinking about doing:
public class SampleData
{
private List<Person> _persons = new List<Person>()
{
new Person { PersonID = 1, Name = "Jack"},
new Person { PersonID = 2, Name = "John"}
};
public List<Person> Persons
{
get { return _persons; }
}
}
So this is a class which mimics data in the DB. Now I want to use this data in my unit tests. In other words, instead of getting data out of the DB, I want to get them out of the datarepository.
I think I can achieve this by stubbing the Repository and by making it use the DataRepository instead:
UC1003_ConsultantsBeherenBL consultantsBeherenBL = new UC1003_ConsultantsBeherenBL();
consultantsBeherenBL = MockRepository.GeneratePartialMock<UC1003_ConsultantsBeherenBL>();
consultantsBeherenBL.Repository = MockRepository.GenerateMock<IRepository>();
This would cause my code to automaticly look for data in the DataRepository instead. So instead of stubbing a method and directly inserting a list (e.g. d => d.Find(Arg.Is.Anything)).IgnoreArguments().Return(a list which you just filled up)) I'd get "real" data back (the data which has been filtered from the DataRepository). This means I can test if my code can really find something, without having to insert test data in my DB (integration test).
How would I go about implementing such a thing? I've tried looking on the web for articles or questions, but I can't seem to find a lot :/
Any help is appreciated.
EDIT: I've tried to SimpleInjector and StructureMap, but I'm stuck implementing one of them.
I'm currently using a repository on my entity framework, so my baseBL looks like this (note: all my other BL's enherit from this one):
public class BaseBL
{
private IRepository _repository;
public IRepository Repository
{
get
{
if (_repository == null)
_repository = new Repository(new DetacheringenEntities());
return _repository;
}
set { _repository = value; }
}
public IEnumerable<T> GetAll<T>()
{
... --> Generic methods
My Repository class:
public class Repository : BaseRepository, IRepository
{
#region Base Implementation
private bool _disposed;
public Repository(DetacheringenEntities context)
{
this._context = context;
this._contextReused = true;
}
#endregion
#region IRepository Members
public int Add<T>(T entity)
... --> implementations of generic methods
As far as I can make out, I now need to be able to say in my tests that instead of using the DetacheringenEntities, I need to use my DataRepository. I don't understand how I switch out my entity framework with a data class, because that data class won't fit in there.
Should I let my DataRepository enherit my IRepository class and make my own implementations?
public class SampleData : IRepository
But I can't do things like this with my lists :/
public IEnumerable<T> GetAll<T>()
{
return Repository.GetAll<T>();
}
Big thanks again for help
EDIT: I realised that a unit test doesn't need a data repository, so I'm just testing that logic in an integration test. This makes a data repository useless, since the code can be tested without a repository.
I'd like to thank everybody for their help though, thanks :)

Use a Dependency injection framework to handle your dependencies. In your unit test you can swap the real implementation with a stubbed one.
In StructureMap for example, you'll say in your code. "All right, now give me the active instance of IDataRepository", for your normal code this would point to an implementation to the real database. In your unittest you can then overwrite this by putting ObjectFactory.Inject(new FakeDataRepository()). The fake repo is then used by all your code, which makes it really easy to test a single unit of work.Í

Related

Unit test for my ViewModel?

I'm new to unit testing and I'm really stuck atm so I could really use some help.
Some application info
I have a WPF application in MVVM. It gets data from a database (classes generated via .edmx).
All linq queries are handled by methods in the Database class.
In CustomerListViewModel, it makes a list of all Customers to be shown in the CustomerListView.
My problem
I am new to Unit Testing. I've read about it and tried to make it work. But as I understand, it should/can be done without touching the DB. I tried to find as much info as I could, but it wouldn't work with what I have. And now I'm basically stuck.
My question
How do I unit test this piece of code? How can I know if I've successfully queried the database (with or without touching the DB in the unit test)?
(If I understand it for this piece, I can figure the rest of the classes and methods out on my own)
The code
CustomerListViewModel:
public CustomerListViewModel()
{
MyObservableCollection<Customer> listCustomers = new MyObservableCollection<Customer>();
ListCustomers = App.Database.GetCustomerList();
}
private void GetListCustomers()
{
ListCustomers = App.Database.GetCustomerList();
if (App.Database.hasError)
App.Messenger.NotifyColleagues("SetStatus", App.Database.errorMessage);
}
Database:
public MyObservableCollection<Customer> GetCustomerList()
{
hasError = false;
MyObservableCollection<Customer> customerList = new MyObservableCollection<Customer>();
try
{
QRM_Entities dc = new QRM_Entities();
var query =
from customers in dc.Customer
select customers;
foreach (Customer cust in query)
{
customerList.Add(cust);
}
}
catch (Exception ex)
{
errorMessage = "GetCustomerList() error, " + ex.Message;
hasError = true;
}
return customerList;
}
The way that you have the ViewModel currently setup will make it almost impossible to unit test.
The issue is on this line:
ListCustomers = App.Database.GetCustomerList();
I presume that App is a static and Database is the class that you are using as your Data Access Layer. So everytime that you call the constructor of your CustomerListViewModel you will call the actual Static implementation of App which you would have to setup before creating the View Model, meaning that you would always be testing with the actual Database, which is obviously what you are attempting to bypass.
In comes my favorite software principle the Dependency Inversion Principle, the premise of this is that decouple modules so that your high level module depends on an abstraction of a lower level module. And that details should depend on that abstraction. Effectively you should develop to an interface and provide this interface to dependents.
Taking your example I would extract interfaces for your database interaction and provide these to your View Model, but I'll go a step further and provide this to a model which will be provided to your view model.
IDatabase:
public interface IDatabase
{
IEnumerable<ICustomer> GetCustomerList();
}
ICustomerListModel:
public interface ICustomerListModel
{
ObservableCollection<ICustomer> Customers
{
get;
}
}
CustomerListModel
public class CustomerListModel : ICustomerListModel
{
private readonly IDatabase database;
private readonly ObservableCollection<ICustomer> customers;
public CustomerListModel(IDatabase database)
{
this.database = database;
this.customers = new ObservableCollection(database.GetCustomerList());
}
public ObservableCollection<ICustomer> Customers
{
get
{
return this.customers;
}
}
}
CustomerListViewModel
public class CustomerListViewModel
{
private readonly ICustomerListModel customerListModel;
public CusomterListViewModel(ICustomerListModel customerListModel)
{
this.customerListModel = customerListModel;
}
public ObservableCollection<ICustomer> Customers
{
get
{
return this.customerListModel.Customers;
}
}
}
So what you can see here is that I have extracted an interface for the database which I request the information from, this means that I don't care about the implementation of the IDatabase, I just now that it provides me with a collection of ICustomer's when I call GetCustomerList().
So I inject a copy of the IDatabase into the CusomterListModel class which I can then query knowing that I'll get what I want back correctly. I then inject the ICustomerListModel into the ICustomerListViewModel so that the collection can be presented to the View.
So to test the CustomerListModel I would have a test like:
[Fact]
public void Customers_IsCorrectlyInitialisedAtStartup_Test()
{
var databaseMock = new Mock<IDatabse>();
var customer = new Customer();
var customers = new [] { customer };
databaseMock.Setup(mock => mock.GetCustomerList())
.Returns(customers);
var sut = new CustomerListModel(databaseMock.Object);
Assert.Equal(customers, sut.Customers);
}
In this I have mocked a version of the IDatabase, now you can see how I don't care in the version of CustomerListModel what IDatabase I have as long as I can call GetCustomerList(). This has a setup to return a ICustomer when a call to GetCustomerList() is called. Finally I am asserting that the Customers collection was correctly populated with the returns of the IDatabase call.
Unit testing is a fine art, difficult to understand at first but when you get it working at first you'll pick it up quickly. Some things you may wish to look at to help you with generating unit testable code and actually testing:
Solid Principles, principles that every Software Engineer should at least be familiar with, will help generating code that is testable.
Dependency Injection, the wiki-page on Dependency Injection outlining the pros and cons to injecting the dependency into a constructor, when and how to use it in further examples.
Moq, a friendly and easy to use mocking framework for C#, which I used as part of my example above.

ASP.Net MVC & Entity Framework project architecture WITHOUT repository pattern

I'm starting a new small project with ASP.NET MVC and Entity Framework. (SQL Server - around 20 DB tables)
In past projects I’ve used Linq2SQL but it seems to be obsolete.
I've read a lot of posts on using repository pattern for EF (pros and cons) , For me it seems better/simpler to code without repository pattern.
I created the following project architecture :
namespace MySite.Models
{
public class User
{
public Int32 ID { get; set; }
public String Email { get; set; }
public String Password { get; set; }
public String Name { get; set; }
public Int32 Gender { get; set; }
}
}
namespace MySite.DAL
{
public class Users
{
public static IEnumerable<User> GetUsers()
{
using (var context = new DatingSiteContext())
{
return context.Users.ToList();
}
}
public static User GetUserByID(int id)
{
using (var context = new DatingSiteContext())
{
return context.Users.Find(id);
}
}
}
namespace MySite.Controllers
{
public class HomeController : Controller
{
public ActionResult Index()
{
ViewBag.Message = "Modify this template to jump-start your ASP.NET MVC application.";
var users = DAL.Users.GetUsers();
return View(users);
}
}
}
What are the disadvantage of using EF like this? (Except lack of unit
testing support)
Is it wrong to create a new DbContext on each call to DAL ? Any Performance hit?
Any other recommended structure for using EF ? Examples? :)
Would you use Linq2SQL in a new project ?
Thank you.
Edit:
The code inside GetUsers() and GetUserByID() is just for example , i understand its a bad practice to return all records from the db (paging or filter in missing)
You actually just created a repository only you call it a 'data access layer' which is, in my opinion, not a good name since Entity Framework is the data access layer. A repository is an abstraction on top of a data access layer, Entity Framework in this case.
Is it wrong to create a new DbContext on each call to DAL ? Any
Performance hit?
Nope, it's just fine, but it might cause trouble when you fetch an entity in one instance of DbContext, and try to update it in another instance.
Would you use Linq2SQL in a new project ?
Nope, Microsoft proposed Entity Framework as the successor of L2SQL and active development of it has stopped.
Any other recommended structure for using EF ? Examples? :)
The approach you use, specific repositories, will result in a lot of redundant code. You could create a generic repository implementing an interface:
public interface IRepository<TEntity>
where TEntity : class, new()
{
IEnumerable<TEntity> GetAll();
TEntity GetById(int id);
IQueryable<TEntity> Table { get; }
}
And an implementation of this:
public EfRepository<TEntity> : IRepository<TEntity>
where TEntity : class, new()
{
private readonly DatingSiteContext _context;
public EfRepository()
{
_context = new DatingSiteContext();
}
private IDbSet<TEntity> Entities
{
get
{
return _context.Set<TEntity>();
}
}
public IEnumerable<TEntity> GetAll()
{
return Entities.ToList();
}
public TEntity GetById(int id)
{
return Entities.Find(id);
}
public IQueryable<TEntity> Table
{
get { return Entities; }
}
}
You can use this repository in your controller like this:
public class HomeController : Controller
{
private readonly IRepository<User> _userRepository;
public HomeController()
{
_userRepository = new EfRepository<User>();
}
public ActionResult Index()
{
var users = _userRepository.GetAll();
var inactiveUsers = _userRepository.Table.Where(u => !u.Active).ToList();
}
}
This generic repository allows you to create mocked repositories:
public class FakeUserRepository : IRepository<User>
{
// ...
}
This approach might seem like a lot of code, but as your entity type amount grows, it will save you a lot of work since all you have to do is create an IRepository<> field in a controller. Yet you have a lot of flexibility with the IQueryable<> property which allows deferred execution.
I'm not saying this is the best method, just one I use regularly in projects. I have to say that I usually write a business (service) layer between the controller and the repositories. I keep my business logic and complex Linq queries (and their execution) there. I also use an IoC container which handles the lifetime of my objects (instances of DbContext and services for example). See this question for more information about that.
My thoughts
Whats the disadvantages:
You cant really unit test anywhere that uses the static methods you have defined in your DAL.
They are also strongly coupled making them more difficult to swap out at runtime, if that became a requirement.
You may start to get additional complications if you need to commit several updates in a transaction
Is it wrong to create a new DbContext on each call?
No, this is fine. The DbContext is lightweight and meant to be used this way.
Other patterns
You already mentioned the repository pattern which is pretty solid, especially when used with a unit of work pattern.
Would you use Linqtosql
No - Linqtosql is pretty much done with, entity framework provides a more complete and generally better solution to this problem
I would rethink how you implemented GetUsers(). You are calling ToList() which will cause all the rows from the underlying table to be returned and stored in memory. If the tables grows large enough you will run into performance issues. It's better to return an IQueryable<User> instead and have your method return context.Users.
Of course you'll run into the problem that the context has already been disposed by the time you execute the IQueryable<>, so you'll need to handle the life cycle of the context in a different way.
If the project is small enough, then you can just store an instance of the Context at the Controller level, and dispose of it when the controller is being disposed. If you do that, make sure you don't do anything in your views that would cause additional queries to be executed (e.g. access a collection off of User if one exists) or else that will error out.

Testing if correct mapper is returned

Hi I am just writting my first unit test and I have a case where I have to test if the correct mapper is returned.
This is my code:
public UserPersonalDetailsDTO GetUserPersonalDetails(int personId)
{
var mapper = ServiceLocator.GetInstance<IMappingService<UserPersonalDetails, UserPersonalDetailsDTO>>();
var userPersonalDetails = UnitOfWork.PersonData.GetUserPersonalDetails(personId);
var userPersonalDetailsDTO = mapper.Map(userPersonalDetails);
return userPersonalDetailsDTO;
}
How would I test if I am getting the correct mapper?
EDIT
I forgot to mention that I am using Unity as my DI Framework this si my constructor:
public ProfileService(IEConnectUow uow, IValidationService validationService, IServiceLocator serviceLocator)
: base(uow, serviceLocator)
{
m_ValidationService = validationService;
}
My CUrrent class inherits from a BaseCLass that have this properties:
protected IEConnectUow UnitOfWork { get; set; }
protected IServiceLocator ServiceLocator { get; set; }
public BaseService(IEConnectUow uow, IServiceLocator serviceLocator)
{
UnitOfWork = uow;
ServiceLocator = serviceLocator;
}
That code is really difficult to unit test. At least two of the dependencies come in via statics (ServiceLocator, UnitOfWork).
I would refactor the code to the following
public class Whatever {
private IMappingService<UserPersonDetails, UserPersonalDetailsDTO> mapper;
private PersonData personData;
public Whatever(IMappingService<UserPersonDetails, UserPersonalDetailsDTO> mapper,
PersonData personData) {}
public UserPersonalDetailsDTO GetUserPersonalDetails(int personId) {
var userPersonalDetails = personData.GetUserPersonalDetails(personId);
var userPersonalDetailsDTO = mapper.Map(userPersonalDetails);
return userPersonalDetailsDTO;
}
}
In the whatever class you can now test the interactions with the objects you pass in. You don't want to be testing that the right mapper is returned in this class. In a unit test, ideally you only want to test the logic of the class and its interactions with dependencies. In this case, I'd simply test the interactions. GetUserPersonalDetails talks to the PersonData object, and uses the Mapper to get the result.
Testing that you get the right mapper isn't the responsibility of this class. Factor that logic out somewhere (perhaps starting with ServiceLocator) into its own class with its own dependencies and verify it does what you want.
Your ServiceLocator is some factory class. If the ServiceLocator is writen by you, you can test is seperately. If it is a libary class, the libary is tested (assumue). You can test is the GetInstance<IMappingService<UserPersonalDetails, UserPersonalDetailsDTO>>(); method is called for the correct types. This can be done with a mocking framework. You make a mock for the GetInstance method and then check if it is called, you know the GetInstance method is right because you have tested it somewhere else.
My test whould look like (pseudo code):
Make mock ServiceLocator.GetInstance
Make mock UnitOfWork.PersonData.GetUserPersonalDetails
Make mock mapper.Map
call GetUserPersonalDetails(int personId)
check if ServiceLocator.GetInstance was correct

NoSQL - How to mock database for unit testing?

I'm researching NoSQL databases and have a question regarding unit testing. What is the appropriate method to unit test the business logic? How does one mock a NoSQL database?
Your business logic should not touch the database directly, but rather go through a database access layer. This lets you mock that intermediate layer for unit testing. To do this, you can use dependency injection and mocking. There are frameworks that can help you with both of these things, but you can also do it by hand. Here's an example:
Say we have a DAL:
public class DBDataProvider: IDataProvider
{
public string getData()
{
//SQL to get data from actual database.
}
}
As you can see, this implements an interface for something that provides data for your business layer. It might look something like this:
public Interface IDataProvider
{
String getData();
}
Your business layer might look something like this:
public BusinessClass
{
private IDataProvider dataProvider;
public BusinessClass()
{
dataProvider = new DBDataProvider();
}
public BusinessClass(IDataProvider provider)
{
dataProvider = provider;
}
public void doBusinessStuff()
{
dataProvider.getData();
//Do something with data.
}
}
So now in your production code, you will make your business class using the default constructor, which will automatically make your class with a connection to the DB. However, notice that we can create a BusinessClass with an IDataProvider that we specify. So, you can make a "fake" data provider just for testing:
public class MockDataProvider: IDataProvider
{
public string getData()
{
//return some expected result that you can control, without doing a DB call.
}
}
Now in your test, you can create a new MockDataProvider, and pass that into the constructor for BusinessClass. Your business class will now use your mock data provider, instead of the real DB.
Here I did everything by hand, but it gives you an idea of how this works. In real life, you can use mocking and dependency injection frameworks to write a bunch of that code for you.
The same way you mock any dependency. Write a nice, neat contract from which implementation details can be abstracted away, then mock that contract. Typically this is done by using the Data Access Layer as the contract(s).
Without getting into real implementation details, lets say you have a query in your method you want to test: (note, i copied this code from a ravenDB example, but i know 0 about ravenDB, so it might not even compile)
public void SomeMethod()
{
var name = "Hello";
var motto = "World";
using (var docStore = new DocumentStore("localhost", 8080).Initialize())
using (var session = documentStore.OpenSession()){
session.Store(new Company { Name = name, Motto = motto });;
session.SaveChanges();
}
}
That's going to be pretty hard to mock / test because it requires a db on localhost on 8080. Now, if you separate this logic out into another class:
public class AwesomeDAL
public virtual void AddCompany(string name, string motto){
using (var docStore = new DocumentStore("localhost", 8080).Initialize())
using (var session = documentStore.OpenSession()){
session.Store(new Company { Name = name, Motto = motto });;
session.SaveChanges();
}
}
and allow for the injection of the dependency (AwesomeDal):
public class ClassBeingTested
{
public AwesomeDal DAL { get; set; }
public ClassBeingTested() : this(new AwesomeDal()){}
public ClassBeingTested(AwesomeDal dal)
{
this.DAL = dal;
}
public void SomeMethod()
{
var name = "Hello";
var motto = "World";
this.DAL.AddCompany(name, motto);
}
}
And you can now test the BL code in isolation. Or you can simulate database exceptions, or anything else you need to test because your data access layer is abstracted, and its implementation is easily mockable with a framework like Moq or RhinoMocks
In addition to the already posted (correct) answers, let me propose an alternative solution: Use a real development database! Nothing is a more realistic mock that the real thing. If you test on it directly, at least you know that your code will actually run.
If you can abstract away your database easily, I recommend doing that, though.

unit testing a unit of work

new to unit testing. I have a unit of work that I am trying to unit test. I am probably missing something simple here. I am trying to unit test the Commit method. I am using nunit and moq.
public class UnitOfWork : IUnitOfWork
{
private readonly DbContext _context;
public UnitOfWork(DbContext ctx)
{
_context = ctx;
}
public void Commit()
{
_context.SaveChanges();
}
}
What do I need to do to test this?
You would insert a mock of the DBContext and then verify that the SaveChanges method is called on commit.
[Test]
public void Will_call_save_changes() {
var mockContext = new Mock<DBContext>();
var unitOfWork = new UnitOfWork(mockContext.Object);
unitOfWork.Commit();
mockContext.Verify(x => x.SaveChanges());
}
You'll need to mock the DbContext, and then verify that SaveChanges was called. Something like Moq can help you here.
That's one way of doing it.
An alternative I've come across is:
Create your edmx file, remove the custom tool so it doesn't autogenerate the entities.
Open the edmx file, right click and add code generation item - go to online templates under database and select the EF POCO mockobject generator. This creates two T4 templates (one for entities and another for the object context and mock object context).
The one T4 template will generate your poco entities for you. The other T4 template will create an interface you can extend to be used as a unit of work which is implemented in an actual object context and a mock object context. Extending it just requires you modify the T4 template to include an additional method on the generated interface (void SaveChanges()) and the implementation of that method on the mock object context.
I've found it to work very well.
Albeit for unit testing purposes, you wouldn't want to test your unit of work (unless verifying certain objects are added/deleted etc.). You would instead test repositories with predefined responsibilities - usually defined within context (ex. patient appointments).
You'd do something like this:
public class PatientAppointmentRepository : IPatientAppointmentRepository
{
//Injected via IOC in constructor
private readonly IUnitOfWork _unitOfWork;
private readonly IPatientAppointmentLogic _patientAppointmentLogic;
public void CreateAppointment(PatientAppointmentModel model)
{
var appointment = ModelMapper.Instance.To<PatientAppointment>(model);
var appointmentAdded = _patientAppointmentLogic.Add(appointment);
if(appointmentAdded)
_unitOfWork.SaveChanges();
}
}
public class PatientAppointmentLogic : IPatientAppointmentLogic
{
private readonly IUnitOfWork _unitOfWork; //Set via constructor
private readonly PatientLogic _patientLogic;
public bool Validate(PatientAppointment appointment)
{
if(appointment == null)
throw new ArgumentNullException("appointment");
//perform some logic here
return true;
}
public void Add(PatientAppointment appointment)
{
if(appointment == null)
throw new ArgumentNullException("appointment");
if(!Validate(appointment)) return; //Or throw an exception, up to you
var patient = _patientLogic.GetById(appointment.PatientId);
if(patient == null) return;
patient.PatientAppointments.Add(appointment);
}
}
It's really up to your to structure it appropiately. You could have another AppointmentLogic repository that has a base validation as an example.
Ideally, generic validation should not depend on external resources (such as a database).
You should be able to create a validation context in one swoop that would be used in further validation (first valid 'cheaply' before you validate 'expensively').
Sometimes all the 'values' you need for the validation is inside an entity you would need anyway, then use that as the validation context.
Best of luck!

Categories