Unit Test Cases with Mocking repository on real data not fake data - asp.net-mvc

I have a basic understanding of Mocking and fake objects, and passing the fake data for Unit test case methods. But is it possible that we can use actual data return by our repositories instead of creating our own fake data to our Unit test methods.
I am using NUnit for a .Net MVC 5 application. As shown below in sample code line :
mockType.Setup(x=>x.GetUserDetails().Returns(
new UserDetail(){ id = 1 , name = "John"}
);
So I need to return the actual data return from method GetUserDetails, instead to create the fake data (as we did in above example).
I need to get the user details from DB table instead of creating fake UserDetail as we did in above example. Please give your advice and let me know if you need more information.
Thanks in advance.

Tests which access other layers of your application called "Integration tests" or "Acceptance tests" if you testing full "pipeline" of your application UI -> Database -> UI.
In your particular case you need to have empty database with exactly same schema as used in the production.
Insert data for test case
Execute test
Assert results
Clean database
Accessing real database, insert data, clean database after every tests will make tests slower - to be slow is OK for integration or acceptance tests.
For keeping testing and production database schema in sync, you should have some maintaining scripts/logistics of your choice.

Related

Is this really an appropriate time to unit test?

I'm working my way through Pro ASP.NET MVC 5 and have just written this method:
public ViewResult Edit(int productId)
{
Product product = repository.Products.FirstOrDefault(x => x.ProductID == productId);
return View(product);
}
This seems pretty straightforward to me, but the author then writes a unit test for it. The test uses MOQ to create a mock repository object, so the only thing being tested is linq. Is the author writing the test as just another example of how to unit test, or is this normal practice? It seems to me that linq generally works and writing my own tests against it is redundant, but this is my first exposure to unit testing.
It depends on how the test has been written, but it likely does more than this.
For example, if the mock repository has been seeded with a Product with the specified productId, and the test also verifies that the related Product object that was seeded was returned from the query, then the test verifies that the function correctly matches the product with the specified id and returns an appropriate view.
With an additional test, which does not seed a Product into the repository, the test can verify that an incorrect product is not matched and that the correct behavior occurs when the product is not present.
Whilst the example seems trivial, the purpose of the unit test is not just to test the function now, it is to create a repeatable test that lives for the lifetime of the code, ensuring that during all future maintenance no subtle change is introduced which causes the behavior to change.
In isolation, many tests may seem trivial and even pointless. En masse, they provide a layer of protection against problems during the long term maintenance of the product.

grails DataSource in Unit Test

I'm trying to bootstrap some data into the in-memory H2 database for use in a domain and service mock test. Here is how I have the test environment's datasource configured:
test {
dataSource {
dbCreate = "create-drop"
url = "jdbc:h2:mem:testDb;MVCC=TRUE;LOCK_TIMEOUT=10000;INIT=runscript from 'sample_bootstrap_data.sql'"
}
}
I am able to do a run-app, access the dbconsole and see all of the data. The problem I'm having is in the service test, with accessing this data. I have a question: How would I access this data in the pre-initialized schema in a unit test?
Unit testing are tests at the "unit" level. In other words you are
testing individual methods or blocks of code without consideration for
surrounding infrastructure. Unit tests are typically run without the
presence of physical resources that involve I/O such databases, socket
connections or files. This is to ensure they run as quick as possible
since quick feedback is important.
Refer this.
You have to use #Mock or #Build.

What's the id generation strategy used in Grails unit test

I have used default id generation strategy in my app (with postgres), and I have a unique sequence table in my db for all my other tables, so an id has to be unique in my table space.
However, I don't have the same behavior in my unit tests, because I have the same id in different tables, I guess that Grails use a different strategy in test? (a sequence per table?)
thanks
By default grails rollbacks DB transactions in the unit / integration tests. That may explain the odd behavior.
You can try to make the unit tests non transactional by explicitly stating that in the Test class.
static transactional = false

Entity Framework 4.1 Integration Unit Tests

First, a few caveats:
We are building a small/medium sized system that is anticipated to have a lifespan of 2-5 years (relatively short). The system is being developed with Entity Framework 4.1, Code First, MVC3. We are trying to push our team towards unit testing / TDD. It is something that we have not done, but we recognize its value so are taking baby steps in that direction.
With all of that in mind, we have decided to build unit tests with Visual Studio 2010's built-in testing framework. We are NOT using the repository pattern or mocks. This is to reduce the complexity and time spent building the unit tests. Each unit test is really more of an integration test - we have a 'test' database that gets initialized each time the tests are run, and each test uses the same controllers that the views use to get as close as we can to real-world behavior of the system.
When commenting or answering this question, please do not attack this approach. I am well aware that this is not TDD in its purest form nor is it the ideal pattern for testing units of work. We are doing it this way to get our feet wet with the technology and try to get the most bang for our buck in terms of time spent building the unit tests.
The Problem:
We are building a lot of unit tests that store an object via a controller, then retrieve the object from the database through the controller to verify that it was stored correctly and that it comes back through our controller the way we would expect. Here is an example:
[TestMethod]
public void Edit_Post_Saves_OperatingCompany_In_DB_When_OperatingCompany_Is_Valid()
{
OperatingCompany opco = new OperatingCompany();
opco.Name = "OpCo - Edit Post - Valid - DB Save";
controller = new OperatingCompanyController();
controller.Create(opco);
Guid opcoid = opco.Id;
controller = new OperatingCompanyController();
opco = (OperatingCompany) ((ViewResult)controller.Edit(opcoid)).Model;
opco.Name = "Edit - OpCo - Edit Post - Valid - DB Save";
controller = new OperatingCompanyController();
HelperMethods.AddValidationResultsToModelState(opco, controller);
controller.Edit(opco);
controller = new OperatingCompanyController();
ViewResult result = controller.Index();
Assert.IsTrue(((IEnumerable<OperatingCompany>)result.Model).Contains(opco));
}
The error we are getting is this:
Test method WebObjects.Tests.Controllers.OperatingCompanyControllerTest.Edit_Post_Saves_OperatingCompany_In_DB_When_OperatingCompany_Is_Valid threw exception:
System.InvalidOperationException: An entity object cannot be referenced by multiple instances of IEntityChangeTracker.
I am pretty sure this is occuring because the entity in question isn't being detached from the context of the first controller, and when we reinstantiate it and try to edit the same entity, it thinks another context still has ahold of it. The reason we are reinstantiating the controller is to ensure that the entity is being pulled back from the database and not just being returned from the cache of the DbContext (please correct me if I am wrong here, but I believe that is what would be happening if we didn't reinstantiate).
We were able to get this to work by explicitly detaching every object from the context after every call to SaveChanges as well as detaching when we query objects via the context in our controllers, but I don't want to do that just to get our unit tests to work, plus I am sure it would be a significant performance hit.
The Question:
Is there some better way to perform this type of integration test with our controllers?
Maybe you can try create new instance of opco before passing it to the Edit(post) action. To simplify creation of copy you can use AutoMapper for example:
Mapper.CreateMap<OperatingCompany, OperatingCompany>();
opco = Mapper.Map<OperatingCompany, OperatingCompany>(opco);

Unit Testing ASP.NET MVC with Data

We have an insanely data driven application. We want to unit test the application but developers are resistant to building entirely fake repositories because of the volume of data. I don't really blame them.
Understand that we are retrofitting tests into an existing application. If we were starting over we would make a ton of architectural changes to facilitate better unit testing with fake repositories.
We would like to distribute a known mdf file with the tests, copy it, and use that for performing our tests. Is there an approved technique for this? I'm familiar with embedding resources into the test dll, but not with embedding mdf's--if that can even be done.
A solution (sort of):
I ended up taking the DataContextWrapper from Andrew Tokeley's post on mocking Linq data contexts (http://andrewtokeley.net/archive/2008/07/06/mocking-linq-to-sql-datacontext.aspx)
and created a FakeDataContext.cs that is basically a bunch of Lists.
I wrote a truly barbaric T4 template (think "select * FROM <#=table.BaseClass.QualifiedName#>") to copy the data from a known good database to create a huge class full of stuff like:
List<Customer> _customers = new List<Customer>();
_customers.Add(new Customer(){CustomerId = 1, CustomerName = "ACME"});
etc.
The class is 25K lines but since t4 writes all those lines, who cares? It allows us to mock just the data context, so we can test our linq against the fake context with some reasonable assurance we got the queries right. The original devs put a ton of business logic in the repo, so it allows us to test the logic against known good data.
Can you set up a test database on a shared server so you don't have to deploy mdf files?
Also, can you wrap all unit tests with TransactionScope?
I've used a test database in my company that contained an well known reference data for all the tests and created a base class for integration tests like that:
[TestClass]
public class ServiceTest
{
private TransactionScope Transaction { get; set; }
[TestInitialize]
public virtual void TestInitialize()
{
Transaction = new TransactionScope();
}
[TestCleanup]
public virtual void TestCleanup()
{
Transaction.Dispose();
}
}
Each test will rollback all it's changes so there's no problem with test data polluting the database.
Have you looked at a mocking framework? If you're code is written in such a way that data dependencies can be injected in to the objects you're unit testing then you should be able to mock those data dependencies.
I have had great success with Moq, but then I wrote my code with dependency injection from the outset.

Resources