Mock Mongo, MongoDatabase.GetCollection and MongoCollection using Moq - mongodb

Can any one please help me in mocking db.GetCollection of MongoDatabase to return mocked data using Moq
//returns MongoDatabase instance
var db = mongoConnector.Connect();
//Return Collection on the type Entity being passed
db.GetCollection<Entity>("CollectionName").AsQueryable().ToList();

Unit testing MongoDatabase sounds like an overkill. I would strongly recommend having data dependent integration tests for your data access layer. Test your core CRUD code using integration tests and clean up/bootstrap the database after each test run. Cleaning up the database on teardown is important as every test should be independent of other.
MOQ can be used to test the business logic layer in which you can mock the data access layer and return expected data instead of hitting the database.

Related

DataSource in Microsoft Test for Entity Framework

I'm creating some test using ms test for an already written routine that use entity framework, and I would like to use the [DataSource] attribute to generate a test routine for a set of data in the database.
My problem is that I can just select a Table and load the single fields in the test, but I would like to fetch directly a set ob ef entities and process directly in the test routine, in a way much more similar to the way the code to test is wrote.
Exist some kind of [EFDatasource] that let me express a Ef query as datasource and use the entity in the test?
thanks,
luca
You should just use a context instance (or service/repository, what have you) in your unit test method and get the entities from it. You can supply the connection string in a config file in the unit test project. This way the test methods will be totally relieved from any connection worries. They just instantiate objects and work with them.
Some will probably comment that this is not unit testing but integration testing and that you should mock the EF context, but that is virtually impossible. Testing EF should be done with... EF.

When I do not expose IQueryable then I have not to do integration tests

I have read lots of SO links about unit/integration testing of the entity framework and to sum it all up if I have not misunderstood:
When the repository interface exposes an IQueryable I have to do integration tests (unit tests are not sufficient) because the IQueryable which is linq to entities can be turned into a linq to objects query which can behave totally different which can only be tested having a real database.
When the repository interface exposes only IEnumerable or List it is enough to unit test the repository.
I know it can be very cool to compose an IQueryable in my service without adding many new interface methods...
But if the above is true and I want to avoid integration tests if possible...
What do you think?
When the repository interface exposes only IEnumerable or List it is
enough to unit test the repository.
No. That is misunderstanding. When repository exposes only IEnumerable or List it is safe to fake or mock it and unit test the logic using your repository. The repository itself must be still covered with integration tests because it defines database queries which must be tested against the real database.
The main reason to hide the query behind the repository is to separate concerns and define strict boundary between application logic and database executed logic (the query). Each logic requires its own tests.
Questions you are referring most probably discussed mocking or faking the EF context / EF sets or repository exposing IQueryable. In such case the repository exposes database executed logic into upper layer which makes correct testing much harder. In such case you need to unit test your application logic and somehow fake Linq-to-entities (database logic) with Linq-to-objects. But such tests are not enough to test those queries so you also need integration tests which will duplicate part of your unit tests.

ObjectContext never derives from an interface?? How do you apply DI/IoC in case of multiple types of ObjectContext?

If you have a system that has multiple types of object contexts. For Eg: BillingObjectContext, HumanResourceObjectContext etc. All derive from ObjectContext but ObjectContext Class does not implement any specific interface like IObjectContext. How would you apply DI/IoC in case of multiple types of ObjectContext say using Ninject?
If you must depend on it in a test, you have to mock it. Here's a sample; it's not much harder than implementing an interface. See also TDD improvements in EF 4.
Why can't we just create the actual context object to be used in our tests? Since we don't want our tests to affect the production database, we can always specify a connection string that points to a test database. Before running each test, construct a new context, add the data you will need in your test, proceed with the unit test, then in the test cleanup section, delete all the records that were created during the test. The only side-affect here would be that the auto-increment IDs would be used up in the test database, but since it's a test database - who cares?
I know that most answers regarding this question propose using DI/IoC designs to create interfaces for data contexts etc. but the reason I am using Entity Framework is exactly to not write any interfaces for my database connections, object models, and simple CRUD transactions. To write mock interfaces for my data objects and to write complex queryable objects to support LINQ, defeats the purpose of relying on highly-tested and reliable Entity Framework.
This pattern for unit testing is not new - Ruby on Rails has been using it for a long time and it's worked out great. Just as .NET provides EF, RoR provides ActiveRecord objects and each unit test creates the objects it needs, proceeds with the tests, and then deletes all the constructed records.
How to specify connection string for test environment? Since all tests are in their own dedicated test project, adding a new App.Config file with a connection string for the test database would suffice.
Just think of how much headache and pain this will save you.
namespace ProjectNamespace
{
[TestClass]
public class UnitTest1
{
private ObjectContext objContext;
[TestInitialize]
public void SetUp()
{
// Create the object context and add all the necessary data records.
}
[TestMethod]
public void TestMethod1()
{
// Runs the tests.
}
[TestCleanup]
public void CleanUp()
{
// Delete created records.
}
}
}

Is there an in-memory provider for Entity Framework?

I am unit testing code written against the ADO .NET Entity Framework. I would like to populate an in-memory database with rows, and make sure that my code retrieves them properly.
I can mock the Entity Framework using Rhino Mocks, but that would not be sufficient. I would be telling the query what entities to return to me. This would neither test the where clause nor the .Include() statements. I want to be sure that my where clause matches only the rows I intend, and no others. I want to be sure that I have asked for the entities that I need, and none that I don't.
For example:
class CustomerService
{
ObjectQuery<Customer> _customerSource;
public CustomerService(ObjectQuery<Customer> customerSource)
{
_customerSource = customerSource;
}
public Customer GetCustomerById(int customerId)
{
var customers = from c in _customerSource.Include("Order")
where c.CustomerID == customerId
select c;
return customers.FirstOrDefault();
}
}
If I mock the ObjectQuery to return a known customer populated with orders, how do I know that CustomerService has the right where clause and Include? I would rather insert some customer rows and some order rows, then assert that the right customer was selected and the orders are populated.
An InMemory provider is included in EF7 (pre-release).
You can use either the NuGet package, or read about it in the EF repo on GitHub (view source).
The article http://www.codeproject.com/Articles/460175/Two-strategies-for-testing-Entity-Framework-Effort  describes Effort  -Entity Framework provider that runs in memory.
You can still use your DbContext or ObjectContext classes within unit tests, without having to have an actual database.
A better approach here might be to use the Repository pattern to encapsulate your EF code. When testing your services you can use mocks or fakes. When testing your repositories you will want to hit the real DB to ensure that you are getting the results you expect.
There is not currently a in memory provider for EF, but if you take a look at Highway.Data it has a base abstraction interface and an InMemoryDataContext.
Testing Data Access and EF with Highway.Data
Yes, there is at least one such provider - SQLite. I have used it a bit and it works. Also you can try SQL Server Compact. It's an embeded database and has EF providers too.
Edit:
SQLite has support for in-memory databases (link1). All you need is to specify a connection string like: "Data Source=:memory:;Version=3;New=True;". If you need in an example you may look at SharpArchitecture.
I am not familiar with Entity Framework and the ObjectQuery class but if the Include method is virtual you can mock it like this:
// Arrange
var customerSourceStub = MockRepository.GenerateStub<ObjectQuery<Customer>>();
var customers = new Customer[]
{
// Populate your customers as if they were coming from DB
};
customerSourceStub
.Stub(x => x.Include("Order"))
.Return(customers);
var sut = new CustomerService(customerSourceStub);
// Act
var actual = sut.GetCustomerById(5);
// Assert
Assert.IsNotNull(actual);
Assert.AreEqual(5, actual.Id);
You could try SQL Server Compact but it has some quite wild limitations:
SQL Server Compact does not support SKIP expressions in paging queries when it is used with the Entity Framework
SQL Server Compact does not support entities with server-generated keys or values when it is used with the Entity Framework
No outer joins, collate, modulo on floats, aggregates
In EF Core there are two main options for doing this:
SQLite in-memory mode allows you to write efficient tests against a provider that behaves like a relational database.
The InMemory provider is a lightweight provider that has minimal dependencies, but does not always behave like a relational database
I am using SQLite and it supports all queries, that I need to do with Azure SQL production database.

Mocking an Entity Framework model?

Is it possible to mock an EF model so that I can test code which uses the model classes without getting rid of LINQ to Entities code strewn throughout my project? Or will it be necessary to set up a test database for the model to hit instead?
You could wrap your LINQ code in Data Access Objects. The DAOs would have separate interface and implementation code. Your test code would mock the DAOs.
If you don't want to do that, you'll need a test DB.