Controller.User is Null During Unit Test - asp.net

I have the following code in my controller action method:
if (User.Identity.IsAuthenticated)
{
// ...
}
It seems to work fine. But when I run a unit test that calls this action, it fails because User is null?
Can anyone suggest the best way to deal with this? Do I have to restructure this code just for unit tests?

You probably need to set the User property as part of your setup. You would do this by mocking the HttpContextBase via ControllerContext used to create the controller so that it returns your mocked user. Set your mocked ControllerContext into the ControllerContext property, and it will find User provided you've configured the object graph correctly.

The User property of the Controller class is copied from the current HttpContext - you have to provide a context and set the User there appropriately for this to work in your unit tests.

User will be null if you run the code outside of the context of a web request. It sounds like you're running tests on your methods directly.
You have two options.
The quickest fix to your problem, but not necessarily the most sustainable fix, would be to simply call your running website from your unit test as a WebRequest.
The more sustainable fix would be to gather your uses of context-dependent server-side functionality (such as User) into a single class that you can mock/fake.
Edit
Can anyone suggest the best way to deal with this? Do I have to restructure this code just for unit tests?
The bottom line answer is "yes". More importantly, you probably want to, because it will make your system more flexible and/or maintainable in the long run.

Related

Symfony2: Access Request object in Entity

I'd like to know how to access the Request object in an entity (Symfony2) to modify the user locale.
If someone has found a solution for my problem, please let me know.
It's not possible. This is by design: the entity is just a simple object that should know nothing about the request - it's the responsibility of the controller to interpret the request, and manipulate the entity based on that.
Something like:
//inside your controller:
public function fooBarAction(Request $request)
{
$entity = // get entity
$entity->setLocale($request->getSession()->getLocale());
}
The above is just example code, it won't work if you just copy and paste it. It's just to demonstrate the general idea. The entity should just be a very simple object, who's only responsibility is to hold some data. It shouldn't know where the data is coming from - that keeps it flexible (if you want to set the locale based on something else, you only have to change your controller, not all your entities).
It is possible, but...
What you can but never should do is inject the Request object into the entity (Practically turning your entity into service, see here). Also, even worse idea (but which people still do), you could inject the whole container and get Request from there. The reason why you shouldn't do it is you never should have any code that deals with business rules or any system code in your entities.
You can switch your locale directly in your routes by using _locale custom variable (accessible also from the Request). Or you can create a kernel listener, which will do the required functionality for you. This way you keep your code testable and decoupled.

best approach to implement getRealPath()

I am working on struts 2.0 . I am designing a web application.
I am using Jasper Report in my application. I want to access the *.jrxml files in my action class. I don't want to give hard coded path to the files. So to get the path dynamically I googled it and got the solution that I can get the path using getRealPath() method. But I found two implementation of doing this:
Using HttpSession to get object of ServletContext and using the getRealPath() method of the ServletContext object.
Like this:
HttpSession session = request.getSession();
String realPath = session.getServletContext().getRealPath("/");
The second approach to do it directly using the static method getServletContext() of ServletActionContext. And then we can get the real path of the application using the getRealPath() method.
Like this:
String realPath = ServletActionContext.getServletContext().getRealPath("/");
Please tell me, is there any difference between the above two and also please tell me whether there is any other way to get the path?
Neither is "better", really, and I'd argue that neither is particularly good, either.
I might try getting the context path in an initialization servlet and stick it into the application context, then make your action(s) ApplicationAware and retrieve the value from the map.
This has the added benefit of aiding testability and removing the static references in the action.
That said, I see zero reason to go through the extra mechanics of your first approach: it adds a lot of noise for no perceivable benefit; I'm not even sure why it wuld be considered.
I'd also be a little wary of tying your actions to a path like this unless there's a real need, what's the specific use? In general you shouldn't need to access intra-app resources by their path.

Asp.net MVC RouteBase and IoC

I am creating a custom route by subclassing RouteBase. I have a dependency in there that I'd like to wire up with IoC. The method GetRouteData just takes HttpContext, but I want to add in my unit of work as well....somehow.
I am using StructureMap, but info on how you would do this with any IoC framework would be helpful.
Well, here is our solution. Many little details may be omitted but overall idea is here. This answer may be a kind of offtop to original question but it describes the general solution to the problem.
I'll try to explain the part that is responsible for plain custom HTML-pages that are created by users at runtime and therefore can't have their own Controller/Action. So the routes should be either somehow built at runtime or be "catch-all" with custom IRouteConstraint.
First of all, lets state some facts and requirements.
We have some data and some metadata about our pages stored in DB;
We don't want to generate a (hypothetically) whole million of routes for all of existing pages beforehand (i.e. on Application startup) because something can change during application and we don't want to tackle with pushing the changes to global RouteCollection;
So we do it this way:
1. PageController
Yes, special controller that is responsible for all our content pages. And there is the only action that is Display(int id) (actually we have a special ViewModel as param but I used an int id for simplicity.
The page with all its data is resolved by ID inside that Display() method. The method itself returns either ViewResult (strongly typed after PageViewModel) or NotFoundResult in case when page is not found.
2. Custom IRouteConstraint
We have to somewhere define if the URL user actually requested refers to one of our custom pages. For this we have a special IsPageConstraint that implements IRouteConstraint interface. In the Match() method of our constraint we just call our PageRepository to check whether there is a page that match our requested URL. We have our PageRepository injected by StructureMap. If we find the page then we add that "id" parameter (with the value) to the RouteData dictionary and it is automatically bound to PageController.Display(int id) by DefaultModelBinder.
But we need a RouteData parameter to check. Where we get that? Here comes...
3. Route mapping with "catch-all" parameter
Important note: this route is defined in the very end of route mappings list because it is very general, not specific. We check all our explicitly defined routes first and then check for a Page (that is easily changeable if needed).
We simply map our route like this:
routes.MapRoute("ContentPages",
"{*pagePath}",
new { controller = "Page", action = "Display" }
new { pagePath = new DependencyRouteConstraint<IsPageConstraint>() });
Stop! What is that DependencyRouteConstraint thing appeared in mapping? Well, thats what does the trick.
4. DependencyRouteConstraint<TConstraint> class
This is just another generic implementation of IRouteConstraint which takes the "real" IRouteConstraint (IsPageConstraint) and resolves it (the given TConstraint) only when Match() method called. It uses dependency injection so our IsPageConstraint instance has all actual dependencies injected!
Our DependencyRouteConstraint then just calls the dependentConstraint.Match() providing all the parameters thus just delegating actual "matching" to the "real" IRouteConstraint.
Note: this class actually has the dependency on ServiceLocator.
Summary
That way we have:
Our Route clear and clean;
The only class that has a dependency on Service Locator is DependencyRouteConstraint;
Any custom IRouteConstraint uses dependency injection whenever needed;
???
PROFIT!
Hope this helps.
So, the problem is:
Route must be defined beforehand, during Application startup
Route's responsibility is to map the incoming URL pattern to the right Controller/Action to perform some task on request. And visa versa - to generate links using that mapping data. Period. Everything else is "Single Responsibility Principle" violation which actually led to your problem.
But UoW dependencies (like NHibernate ISession, or EF ObjectContext) must be resolved at runtime.
And that is why I don't see the children of RouteBase class as a good place for some DB work dependency. It makes everything closely coupled and non-scalable. It is actually impossible to perform Dependency Injection.
From now (I guess there is some kind of already working system) you actually have just one more or less viable option that is:
To use Service Locator pattern: resolve your UoW instance right inside the GetRouteData method (use CommonServiceLocator backed by StructureMap IContainer). That is simple but not really nice thing because this way you get the dependency on static Service Locator itself in your Route.
With CSL you have to just call inside GetRouteData:
var uow = ServiceLocator.Current.GetService<IUnitOfWork>();
or with just StructureMap (without CSL facade):
var uow = ObjectFactory.GetInstance<IUnitOfWork>();
and you're done. Quick and dirty. And the keyword is "dirty" actually :)
Sure, there is much more flexible solution but it needs a few architectural changes. If you provide more details on exactly what data you get in your routes I can try to explain how we solved our Pages routing problem (using DI and custom IRouteConstraint).

Test presenter in ASP.NET Web Form

I am working on an ASP.NET WebForm application using MVP pattern. For every Web Form, there is a Presenter class associated to handle UI and Business logic. However, I had problem when writing unit tests for Presenters, since session values are used in presenters. And there is no HTTP context exists during execution of the unit test ( BTW I use nUnit ), making it is impossible to write unit test for presenters.
Anyone can explain how to unit test these presenters?
Thanks
you can either mock or stub out an IHttpContext and let your framework inject the real HttpContext or you can wrap the session, cookie, ... state behind some interfacing, or you could use "Moles" from Pex, the interfacing is explained here http://haacked.com/archive/2007/09/09/ihttpcontext-and-other-interfaces-for-your-duck-typing-benefit.aspx
You can change your Presenter class to have a dependency on HttpContextBase. Once that is done, you can supply a mocked version of the HttpContext to your presenter class for testing. In production, you would simply supply the HttpContext.Current property.
Hm, I would suggest another approach.
I think your presenter should not be aware of HttpContext, PageLifeCycle etc. because you have to test it in isolation. So rather than trying to mock IHttpContext, try to extract values that you need in presenter(you don't need whole httpcontext object right, just some values from session, cookies etc) and inject in presenter through presenter constructor. Now you can test it properly.
Cheers

How to unit test server controls on postback?

I am trying to create my own EasyBinderDropDown that currently looks like this:
public class EasyBinderDropDown : DropDownList, ICanBindToObjectsKeyValuePair {
public void BindToProperties<TYPE_TO_BIND_TO>(IEnumerable<TYPE_TO_BIND_TO>
bindableEnumerable,
Expression<Func<TYPE_TO_BIND_TO, object>> textProperty,
Expression<Func<TYPE_TO_BIND_TO, object>> valueProperty) {...}
public bool ShowSelectionPrompt { get; set; }
public string SelectionPromptText { get; set; }
public string SelectionPromptValue { get; set; }
//...
}
Basically it is very helpful for easy binding to objects from inside code since you just do something like _dropDown.BindToProperties(myCustomers, c=>c.Name, c=>c.Id) and it works for you, also by setting ShowSelectionPrompt and SelectionPromptText I can easily have a "Select Customer" Line. I don't want to ask so much about my specific implementation, rather I am confused how to write unit tests for some scenarios.
For example my current tests cover the control being created properly during load and having its output render properly but I am lost as to how to test what happens when the control gets posted back. Can anyone give me some advice on how to test that? I would prefer to do this without having to mock an HTTPContext or anything like that, Is there a way I can simulate the control being rebuilt?
"I would prefer to do this without having to mock an HTTPContext or anything like that, Is there a way I can simulate the control being rebuilt."
By definition, you are not asking to "unit test"; you are looking for an "integration test". If you are not mocking the major dependencies, in this case, the ASP.NET runtime components, the what you are testing is the integration between your control and ASP.NET.
If you do not want to mock out the HttpContext and friends, then I would suggest an automated web testing framework such as Selenium or NUnitAsp.
Update: Based on the comment. Don't have the code access directly the IsPostback or other asp.net stuff. Wrap them with simple classes/interfaces. Once you have done that, send mocks that implement those interfaces. This way you don't have to mock the whole HttpContext, just the pieces that matter for the code (which are really clear based on the interfaces involved).
Also, given it is an asp.net custom control, you don't want to force requirements on external things like dependency injection. Have a default (no parameters) constructor, that sets up the control to use the asp.net stuff. Use a constructor with more parameters to send the mocked versions.
Initial answer:
It seems to me you are looking for a happy middle between unit tests and integration tests. You are working with a custom control, which can go wrong on different parts of the asp.net's page lifecycle.
I would:
Check if you can move parts of the code
out of the custom control to separate
classes, you can more easily unit test
For simple scenarios, rely on the functional tests of the rest of the project to catch any further issue with the control (use watin / selenium rc).
For more complex scenarios, as if the control will be used in different parallel projects or will be delivered to the public, set up some test pages and automate against it (again watin / selenium rc).
You write the tests in watin / selenium rc in c#, and run them in your "unit" test framework. Make sure to keep them separated from the unit tests, since they will clearly run slower.
Ps. I haven't used ms test support for asp.net, it might have some support for what you are looking for.

Resources