For my ASP.NET MVC3 (new) development, I don't want to create a dependency on MvcContrib TestHelper (and thus Rhino Mocks) unless it is providing significant value. So I'm seeking to understand the current status of this helper.
The documentation says that TestHelper produces fakes for the following controller dependencies:
HttpContext
HttpRequest
HttpResponse
HttpSession
Form
TempData
QueryString
ApplicationPath
PathInfo
For MVC1 and MVC2 I can see why this was so helpful. But MVC3 started to introduce improved test "seams" which may have made TestHelper less pertinent. For example, the MVC3 Request and Response controller properties were designed specifically to be isolateable/injectable versions of HttpRequest and HttpResponse.
As I'm still exploring testability advancements in MVC3, I'd like to know how many of the other dependencies listed above have received improved isolation (or injectability) in MVC3. I'd also love to see samples of code showing what it looks like in MVC3 to create tests with fakes (stubs / mocks) for the above dependencies WITH and WITHOUT using TestHelper.
If the differences in test-writing with and without TestHelper are sufficiently marginal, then I'd prefer to forego TestHelper...which means I am then free to choose whatever isolation framework I like (MOQ or NSubstitute).
Ultimately I would be surprised to learn the MVC3 release had taken specific improved testability steps for HttpRequest and HttpResponse, but not for the other above listed dependency issues. I'm hoping someone can give a break-down of how the above items are isolated without using TestHelper.
But MVC3 started to introduce improved test "seams" which may have
made TestHelper less pertinent. For example, the MVC3 Request and
Response controller properties were designed specifically to be
isolateable/injectable versions of HttpRequest and HttpResponse.
MVC didn't introduce absolutely anything new in respect to the objects you have listed in your question in terms of unit testabaility. They were abstractions in ASP.NET MVC 1 and 2 and are abstractions in ASP.NET MVC 3. This allows you to unit test your controller actions and code that depends on them in isolation. But in order to do that you need to mock those dependencies. That's where a mocking framework comes into play. Rhino Mocks is just one possible framework. MVCContrib.TestHelper provides a really nice and fluent syntax to unit test controller actions. Personally I use it all the time. It really makes the unit tests more readable and avoids cluttering them with all kind of plumbing, mocking and infrastructure code.
Check this unit test for example: https://github.com/darind/samplemvc/blob/master/tests/SampleMvc.Web.Tests/Controllers/UsersControllerTests.cs
ASP.NET MVC 3 introduced a dependency resolver and providers which allows you to inject dependencies into many other parts of the framework other than simple controllers and thus unit test those parts which previously were difficult. For example action filters.
But in terms of the actual unit test it doesn't change anything:
you create a mock to represent some object that the subject under test depends upon and that you can control in your unit test
you define expectations on the mocked object
you call the actual method you are testing
you assert on the results
Related
For the project I am doing in my internship we have to use a repository pattern. Since the project was already using EF Core and I read that there was already repository and unit of work in the underlying implementation. I figured I would just use the EF Core methods directly without implementing repository classes as I wanted to prevent clutter.
Well now I am in a bit of a problem, I can't seem to find much useful information on unit testing when I implement this way. The requirement is a hard requirement, and I required 100% coverage of CRUD functions within my controllers due to the standards of this firm. I found some of the Microsoft Documentation here, here, and the integration testing using SQLite but I still can't seem to figure out unit testing. I did some googling as well and I can't find resources aside from integration testing.
Is there some way I can unit test using EF Core directly, or am I gonna have to make repositories in order to properly unit test this program?
Since you do not have a separate repository, you do not have to unit test your repository; you cannot unit test what you don’t have.
What you would usually test with EF Core would be actual database access. For that, you can use the in-memory database to temporarily set up your database which you can run full tests against. Of course, this is more an integration test than a minimal unit test.
But you should think about this: When you write unit tests, you have to have an actual idea of what you are testing. Just saying “I need unit tests for component X” does not make real sense. Usually, it would be more like “I need unit tests for methods U, W, Y of component X”. So unless you actually have methods with real behavior that you need to test, attempting to write unit tests for the database context just makes no sense.
You only want to unit test things things that you write yourself. If there’s nothing, e.g. because you are using the direct database context functionalities for CRUD, then there’s nothing to test. The EF Core project is already covering their side with unit tests, and you probably don’t want to start unit testing third party code here.
With EF Core you may use InMemoryDatabase, mock data of your DbContext and test your methods against this data.
Repository adds additional abstraction layer and makes testing a bit more transparent, but it is also possible to inject DbContext with mocked data for your unit tests.
Some code to illustrate an idea
Just don't forget to check is InMemoryDatabase was already passed to the context and do not add another provider in that case.
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
if (!optionsBuilder.IsConfigured)
{
optionsBuilder.UseSqlServer("ConnectionString");
}
Tip
If you are using ASP.NET Core, then you should not need this code since your database provider is already configured outside of the context (in Startup.cs).
I've spent days trying to mock, stub and fake my way to a testable application. I usually don't test controller actions, but test all my other classes and patterns instead.
The wall I hit was with the new attribute routing feature. While I can use the routing classes to register my rules etc. I get this error when MapMvcAttributeRoutes is called.
This method cannot be called during the application's pre-start initialization phase
This is discussed here.
MapMvcAttributeRoutes: This method cannot be called during the application's pre-start initialization phase
To be honest, I can't understand the answer(s). Not the code, but its fragmented into versions, links to other bugs, GitHub etc.
I'm a bit lost as to the bottom line answer:
As of 23rd October, 2014. Is it possible to register all routes under test conditions, what version of MVC do I need and which classes/methods do I call to do it?
At present, my classes using UrlHelper are screwing up because needed routes are missing. I am injecting subclasses to bypass the issue, but I don't think its unreasonable to fake the runtime MVC environment and have my app run without lots of DI acrobatics.
It would be nice if these was a simple helper in the framework itself that could take a JSON object describing a raw HTTP request and have the Controller, HttpContext, ControllerContext etc. etc. all created properly as if it were a real request off the wire.
Thanks,
Luke
Good question, and I think that the answer is that little or no thought was given to testing routes in the design of this part of the framework. There may be ways to test routes, but they will be indirect, undocumented and prone to break when a new version of MVC ships.
I have a blog post here on my experiences on the topic. I also suggest that you also campaign for better testability in ASP vNext in the public issue tracker.
During a daily stand-up, a colleague mentioned he was integration testing via an in-memory web server. Intrigued, he showed me how and I was amazed, learnt something :-)
You can new-up an HttpServer instance and have it read your config and then invoke the server instance. I have not tried it, but I see no reason why this wouldn't enumerate your routes and code needing proper config will all work.
This SO question is related and may help in how to set this up:
How does the In-Memory HttpServer know which WebAPI project to host?
In an MVC4 C# website, we are using Unit Testing to test our code. What we are currently doing is creating a mock database, then testing each layer:
Test the Database - connecting, initializing, load, etc.
Test the code accessing the database
Test the view layer
I want these three categories to be run in order and only if the previous one passed. Is this the right way to go about it? The old way we were doing it was using a Dependency Injection framework was a weird approach to mock testing. We actually created a mock class for each data accessor, which sucks because we have to re implement the logic of each method, and it didn't really add any value because if we made a mistake with the logic the first time, we'll make it a second.
I want these three categories to be run in order and only if the
previous one passed. Is this the right way to go about it?
No. You should be test everything in isolation and because of that any failing data access code should be completely unrelated to the view. So the view unit tests should fail for a completely different reason and because of that you should always run all tests.
In general, tests should run in isolation, and should not depend on any other tests. It seems to me that the view layer still depends on the data access code, but that you only abstracted the layer below. In that case, from the view's perspective, you are mocking an indirect dependency, which makes your unit tests more complex than strictly needed.
The old way we were doing it was using a Dependency Injection
framework was a weird approach to mock testing
I'm not sure if I get this, but it seems as if you were using the DI container inside your unit tests. This is a absolute no-no. Don't clutter your tests with any DI framework. And there's no need to. Just design your classes around the dependency injection principle (expose all dependencies as constructor arguments) and in your test you just manually new up the class under test with fake dependencies -or- when this leads to repetitive code, create a factory method in your test class that creates a new instance of the class under test.
We actually created a mock class for each data accessor, which sucks
I'm not sure, but it sounds as if there's something wrong with your design here. You would normally have a IRepository<T> interface for which you would have multiple implementations, such as a UserRepository : IRepository<User>, and OrderRepository : IRepository<Order>. In your test suite, you will have one generic FakeRespository<T> or InMemoryRepository<T> and you're done. No need to mock many classes here.
Here are two great books you should definitely read:
The Art of Unit Testing
Dependency Injection in .NET
Those books will change your life. And since you'll be reading anyway, do read this book as well (not related to your question, but code be a life changer as well).
What is the basic unit testing of a web app created using ASP.NET MVC and C#. I'm using MySQL as my backend database. Do I need to create a unit test for the controller class and for the Model class? I want to use NUnit framework and NMock framework. And as I read the articles for using the NMock, I should use and Interface for my unit test but my codes doesn't have interface. Do I need to modify my web app codes and add some interface or there are another ways for this?
Please advise.
Many thanks.
If you have tight coupling in your code then you will find it hard to test each part of your application in isolation, and very difficult to mock dependencies.
So if your controller depends on SomeService then extract a new interface ISomeService and depend on that. This is where using an IoC container to inject your dependencies will also help you and promote loosely coupled code.
In a typical n-tier MVC application we would unit test our data access layer, service layer (mocking the data access layer dependency), MVC controllers (mocking the service layer dependency).
I don't tend to test my views/viewmodels because they are pretty dumb anyway.
When I first started MVC I read the Pro ASP.net MVC 2 book by Apress and I'd highly recommend it (Although the MVC 3 book comes out in a few weeks). It explains how to design your site so that it can be effectively unit tested. It also uses NUnit and Moq for testing. http://amzn.to/iIfij4
My controllers are utilizing StructureMap and AutoMapper. Presently, there is nothing exceptional with my routes. For the basic CRUD controller actions what tests should I be writing to ensure good code coverage?
It is difficult to say what you have to test in your controllers without showing them. You say they are basic CRUD but then you talk about AutoMapper, so probably it's not as simple as that. Here's an example of unit test I wrote and the controller being tested.
I have been doing the same thing recently. From my research it seems that best practice is to create at least one test for each action (That way you cover CRUD by virtue of the fact that your actions are generally based on CRUD) and limit the test to the internal code. What that means is don't cross the method boundary but rather mock out everything your action needs and assert the desired results. Of course this means that you need to do the same thing for your services, repositories etc
But it means that you have a unit test that won't break if you change some code between the action and the DB unless you have a change to make. It is time consuming but so far I have found the effort well worth it as a failed unit test in unrelated code means I have a change to make I forgot about or I am too tightly coupled.