Test presenter in ASP.NET Web Form - asp.net

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

Related

How to provide capability like OnActivate (in Autofac) in Mvx.IoCProvider.Register

Autofac provides the OnActivated() method, which provides the capability to run any action after constructing a registered type.
Is possible to use a similar method in MvvmCross? Do you have any ideas to provide the same functionality?
It usually pays to understand the fundamentals of Dependency Injection (DI) instead of relying on particular DI Container features. Ask yourself the question: If I didn't have a DI Container, then how would I solve my problem?
Ironically, it turns out that things are usually much simpler with Pure DI.
If you didn't have a DI Container, then how would you run an action after construction of an object?
The easiest solution is to provide a factory that creates and initialises the object. Assuming the same API and requirements as the Autofac documentation implies, you could do this:
public static Dependency2 CreateDependency2(ITestOutputHelper output, Dependency1 dependency)
{
var d2 = new Dependency2(ITestOutputHelper output, Dependency1 dependency);
d2.Initialize();
return d2;
}
If you still must use another DI Container, most of them enable you to register a factory like the above against the type. I don't know how MvvmCross works, but I'd be surprised if this wasn't possible. If it isn't, you can implement an Adapter over your actual dependency. The Adapter would take care of running the action on the adapted object.
FWIW, if an object isn't in a valid state before you've run some action on it, then encapsulation is broken. The fundamental characteristic of encapsulation is that objects protect their invariants so that they can never be in invalid states. If possible, consider a better API design.

Request.Querystring is null when use unit test

I want to create Nunit test case for ASP.NET MVC application. If the ASP.NET uses Request.QueryString or Request.Url. then the unit test case will return null reference exception since the Request.querystring will return the value if the control comes from UI only.
So can you please help on this to create a unit test for MVC controller which uses Httpcontext.Request attributes.
Your unit test runs outside of the HttpContext and therefore you either need to mock the HttpContext or change your architecture to work around the problem, an example of this is shown below:
http://volaresystems.com/Blog/post/Dont-mock-HttpContext.aspx

Controller.User is Null During Unit Test

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.

How does ninject work at a high level, how does it intercept object instantiation?

At a high level, how do these dep. injection frameworks work?
I can understand if you always instantiate an object via a custom factory like:
IUser user = DepInjector.Get<User>();
I'm guessing what happens is, wherever you defined the mappings, it will look at the type you want and try and find a match, if found, it will via reflection instantiate the type.
Are there dep. inj. frameworks that would work like:
IUser user = new User();
If so, how would it get the correct user, where is it hooking into the CLR to do this? In case of an asp.net website, is it any different?
If you want to know how Ninject works then the obvious place to start would be reading How Injection Works on their official wiki. It does use reflection but it now also uses dynamic methods:
"By default, the StandardKernel will
create dynamic methods (via
System.Reflection.Emit.DynamicMethod)
that can be used to inject values into
the different injection targets. These
dynamic methods are then triggered via
delegate calls."
As for you second example, I don't believe there are any DI frameworks that would do what you ask. However, constructor injection tends to be most common way of implementing IoC, so that when a class is constructed it knows what type to bind to via some configuration binding. So in your example IUser would be mapped to concrete User in config bindings so that any consuming class that has an IUser parameter as part of its constructor would get the correct User type passed in.
AFAIK there's no way to "hook into" object instantiation with the CLR. The only way to use DI in the second case would be to employ an assembly rewriter (i.e. a postprocessor similar to PostSharp) to replace the call to new with a call to the DI factory method (i.e. GetUser) in the compiled code.

Right place to initialize an object in ASP.NET MVC

I am new to the MVC way of programming so please bear with my basic question !
I have a Status class with a default constructor (in an ASP.NET MVC application).
public Status()
{
this.DatePosted = DateTime.Now;
}
I noticed Fluent NHibernate calls this constructor each time it fetched a list of existing Status objects from the database. Hence, the constructor does not seem like the right place to initialize the date.
Where should I move this initialization ? Moving it to the Controller (Add action of Status controller) also seems to violate the principle that the Controller should not make any business decisions. Should I move it to the Status DAO then ? (In traditional ASP.NET Web Form applications I worked with, a DAO simply accepted a business object and saved it to the database and did not contain any logic)
I would like to know the right way to accomplish this. Is there another layer I am missing here where this initialization should take place?
I noticed Fluent NHibernate calls this
constructor each time it fetched a
list of existing Status objects from
the database. This does not seem right
This is exactly what is supposed to be happening. Why wouldn't an ORM call the default constructor for an object? I think every hand rolled DAL and ORM in the world would trigger DatePosted to be reset because thats just how constructors work.
Your DatePosted property should probably set via ModelBinding or manually in the controller and not be part of a constructor.

Resources