Property injection on attributes not working from a unit test - asp.net-mvc

During execution as an Asp.Net Mvc application, property injection by autofac works successfully, as documented here:
http://code.google.com/p/autofac/wiki/Mvc3Integration#Filter_Attribute_Property_Injection
If I carry this same logic through to a (nunit) unit test, the properties are not being injected on my custom attribute. Is there something specific in the mvc extensions that would cause this not to work from a unit test?
Thanks

Filter attribute property injection works as part of the MVC/ASP.NET pipeline, not as something available as a standalone feature.
You'll probably notice that the filters on an MVC controller don't actually execute during unit tests either. For example, put the HandleErrorAttribute on your controller action and throw an exception from that action in a unit test. Notice how the HandleErrorAttribute didn't get invoked to try to send you to the error view?
This is because in a unit test scenario, you're not in the MVC pipeline - you're testing controllers/actions as POCO (Plain Old CLR Objects). You won't get model binding, filters, HttpModules, or anything else that you'd normally see as part of real integration/execution.
That's not an error, that's by design. It's similar to the way you can unit test WCF service implementations and if you attach behaviors to them via your web.config you won't see those behaviors in the unit test. Your unit test isn't executing in the pipeline, it's executing only against the one class as a standalone entity.
If you need to test how the whole thing works together with filters and all - an integration test - you'll need to look into retrieving the content from a running version of your web application using browser automation or some other programmatic web client mechanism. For the pipeline to be in place, you have to actually be running in a real, full runtime, not in a standard/standalone unit test environment.
As far as whether it's OK to use DI in unit tests or not... that's more a personal preference. I use it in some of my tests, but when I do, I wire up mocks/stubs as the dependencies so I can control the interaction between my system under test and its dependencies. You don't need DI to do that. You could just construct all the fake dependencies manually and poke them in without any DI/IoC container at all. That said, in a unit test environment, you shouldn't be wiring up The Real Dependencies because then you're not testing your class as a unit - that's an integration test.

You should avoid using DI for unit testing. Unit testing is all about testing the functionalities of the a particular piece of code and not others. In your case if you are testing the custom attribute then you should set the dependencies directly without relying on any IoC container to do that.
Most of the cases the dependencies would be replaced by mock objects instead of the real ones.

Related

Accessing NInject kernel from a dependent assembly

I have an ASP.NET MVC 5 project where I need to use a custom web-service based e-mail service (long story! Can't change it, though).
I wrapped up the e-mail web service into a separate assembly and packaged all the dependencies in there.
In my ASP.NET MVC 5 app, I'm using Ninject for dependency injection, and it works really well inside the MVC project - the controllers get their dependencies injected "magically" , and it's a joy to use.
But now: for my e-mail sending component, I'd like to write a "mock" or simulator for use locally when doing development. So basically, I would need to be able to bind the IMailService to both the MailService (real implementation), as well as the MailServiceSimulator (my dummy implementation). Ninject supports that, no problem:
Bind<IMailService>().To<MailService>().Named("Production");
Bind<IMailService>().To<MailServiceSimulator>().Named("Simulator");
BUT: the problem is this: I register all the dependencies with Ninject in the MVC application (in the NinjectWebCommon class in App_Startup) - but I'd like to be able to have a factory class in my "mail service" project that can be told to return a real implementation - or the simulator - for the mail sending component. But how can I get access to the Ninject kernel in order to get the desired service?
Somehow, I'd need to be able to do either
return kernel.Get<IMailService>("Production");
if the real implementation is desired, or
return kernel.Get<IMailService>("Simulator");
if the development-time simulator for the IMailService should be used.
Since my MVC app already uses the "MailService" assembly as a reference, I cannot really make the "MailService" use the "MVC" project as a reference.... so how can I access the Ninject kernel (that gets created inside the "MVC" assembly at startup) from within a referenced "MailService" assembly?? Seems I'm going in circles, one assembly requiring the other and then the other requiring the first one again as a dependency.....
Any ideas?
Accessing the Kernel, or doing DI business, in your MailService project seems like a leaky abstraction.
Assuming the "Production/Simulator" switch is located in the appSettings as a "MailSwitch" setting, you may leave out the named bindings and go for :
Bind<IMailService>().To<MailService>()
.When(r => ConfigurationManager.AppSettings.Get("MailSwitch")=="Production");
Bind<IMailService>().To<MailServiceSimulator>()
.When(r => ConfigurationManager.AppSettings.Get("MailSwitch")=="Simulator");

How to inject 3rd party IOC container into ASP.NET Core Startup class

I'm creating a web API using ASP.NET Core, and I'm using SimpleInjector as my DI framework. I understand the basics of how to use SI with ASP.NET Core; my problem is more an architectural one.
I have a project with integration tests for the API project, in order to test the raw API endpoints and responses. Naturally, the test server (set up using Microsoft.AspNetCore.TestHost) should use the API project's real Startup class.
The problem lies in where to register mocks for the controllers' dependencies, because I don't want to have all the production implementations being registered when testing: Firstly, most of them are, of course, dependencies used by the production implementations of the controller dependencies I'll be mocking in the first place; and secondly, in case I update my controllers and forget to register mocks of the new dependencies, I want my code to fail (container verification) instead of silently using production dependencies that are present in the container.
Thus, the dependencies can't be registered in the Startup class. That's fine by me – I think I'd rather keep the composition root in a separate assembly referencing all other assemblies, anyway. AFAICS the ASP.NET Core project would need to reference this project, which exposes a single method that returns a pre-registered container that can be used in the Startup class, where it's needed to register e.g. the controller activator (and will undergo final validation).
But this begs the question: How to get the container – being already registered with all my application components (whether production implementations from the composition root project, or mocks from the integration test project) – into my Startup class?
My initial solution is to simply have a static property on the Startup class called e.g. Container, and assign that before using WebHostBuilder. This seems "pragmatically robust": The application will fail fast (NullReferenceException) if it's not set before the Startup class is run, and the property is only used during setup, so I don't really need to guard against it being set multiple times or being set to null or any such thing – if it's assigned before startup, it works, if not, it won't start.
Does this seem like a solid solution, or am I oblivious to any obvious ways this will will come back to bite me later on? Are there any better solutions?

How do I test the URL mapping for a grails web service

I'd like to test the URL Mappings for a simple REST web service that I'm setting up in Grails. The problem is that the URL mappings are defined with the HTTP method:
class UrlMappings {
static mappings = {
"/blah/$city/$date"(controller:"blah"){
action = [GET:"show", PUT:"update", POST:"save"]
}
}
}
The GrailsUrlMappingsTestCase doesn't seem to support passing in an HTTP method, it just takes a URL and a list of assertions.
Is there a way to get the GrailsUrlMappingsTestCase to play nice with RESTful webservice mappings? Or, is there a different way or better to test URL mappings?
The original code has not this feature. I see two possibilities how to do test REST service.
1) Functional test
You can setup a functional test which tests your app on running web container. Your application will be deployed and functional test will run. The tests are Unit tests again.
Take a look on grails functional testing or functional testing plugin.
2) Extend GrailsUrlMappingsTestCase
Since grails is open source you can extend GrailsUrlMappingsTestCase and add this feature. The source code for this class looks quite simple.

Unit Testing rich Views for ASP.NET MVC

If I have a rich AJAX-driven GUI in ASP.NET MVC, how would I unit test that effectively using a framework like NUnit?
If you're looking to test the functionality of the UI, use browser automation tools like Selenium.
jQuery has a unit testing project called QUnit which you could use to test your ajax code from a client. It isn't going to integrate with NUnit, but it is another option.
With NUnit, you would primarily be testing your controller actions -- i.e., given a set of parameters and a configuration, does the method return the correct result and view model. If you need to test your client-side javascript, you should look at either a javascript unit testing framework or a UI testing tool, such as Selenium or WatiN.
You can use Selenium IDE to record tests and the generate NUnit testcases to verify behaviour and output of your views.
Steve Sanderson also blogged earlier on today about HtmlUnit on .NET as 'headless browser'. (Testing using the Selenium server can be slow, because it requires creating an instance of FireFox, IE etc);
You would have to unit test your ajax calls and not your UI per se., For example if you are getting some json data through a ajax call, this would translate to a controller method which can be unit tested.
I you want to unit test something which happens after the data reaches the browser then its a whole different ball game and not related to MVC.

Can we unit test View ('V') of MVC?

Duplicate: Unit Testing the Views?
Is there any way to unit test View?
I am sure that we can test Model & Controller but don't know how to unit test View?
Is that worth testing View?
You can enable compilation of MVC views. That helps a lot. Otherwise, I don't think it is worth it. After all, the there are only two things that you are interested in. Does view compile and do you get any exceptions (null, out of bounds exceptions, or similar)?
There are some folks who claim that you should not include any logic in view. Write helpers for anything. In that case, compilation is pretty much everything you'll want.
We decided to invest into WatiN testing. It tests views and it tests the whole app at the same time. Has some nice helpers, but requires constant maintainance.
Haven't views abandoned code behind now? So what are you going to test? If you are testing the controller, then you just need a succesful view result to show that the view works. Rather than going to the trouble of pre compiling views or whatever, this will start to drag any sizeable project down in terms of continuous integration, and build.
From what I have read (in Pro ASP.NET MVC Framework by Steven Sanderson), views are not considered worth testing. ASP.NET MVC viewes can be generated using various engines, e.g. the default lightweight ASPX, or for example http://www.stringtemplate.org/. For ASPX output you might run some HTML syntax checker tool, and for other view engines the fact that the views compile successfully should be a good enough test ;)
I do not see the point of unit testing the views, since they don't contain much logic. You can however to some integration testing/UI testing using a tool like WatiN.
Example of a test written in WatiN:
[Test]
public void SearchForWatiNOnGoogle()
{
using (IE ie = new IE("http://www.google.com"))
{
ie.TextField(Find.ByName("q")).TypeText("WatiN");
ie.Button(Find.ByName("btnG")).Click();
Assert.IsTrue(ie.ContainsText("WatiN"));
}
}
You should not try to test everything using tool like this. Select some key functionality of the application, and write test for them.
For those who do not see the value in testing views.... How can you be sure that the view has the right attributes on elements, or that it is bound correctly?
Many answer "at a higher level" (such as running the site and using tools such as selenium or equivalent).
However these techniques make it virtually impossible to prove that the source of the error is in the view itself and also require massive changes to the server side code so that the views can be rendered in a targeted manner.

Resources