Why does my asp.net mvc controller not call it's base class' Initialize method during unit tests?

When you make a request to a controller through a website the MVC framework picks up that request and runs it through a number of different steps. Somewhere in that pipeline of steps MVC knows that it must call the Initialize method so it finds the Initialize in your MyBaseController class and executes it. At this point all is well and everything works When you create a new instance of your HomeController in your test code you're simply creating a new instance of a class.

You're not running that class through the MVC request pipeline and you're test framework doesn’t know to execute the Initialize method so you get an error Personally I would look to test the Index action independently of the Initialize method. Your Index action above is empty so I can't see exactly what you're trying to do but if you are returning one view for logged in users and another for anonymous users I'd do something like this: TestMethod public void Index_Shows_When_Not_Logged_In(){ HomeController controller = new HomeController(_unitOfWork); controller. CurrentUserId=0; controller.Index(); //Check your view rendered in here } TestMethod public void Some_Other_View_Shows_When_Logged_In(){ HomeController controller = new HomeController(_unitOfWork); controller.

CurrentUserId=12; //Could be any value controller.Index(); //Check your view rendered in here } There are some pretty nifty test helpers in the MVC contrib project ( http://mvccontrib.codeplex.com ) which allow you to do things like: controller.Index(). AssertViewRendered().

When you make a request to a controller through a website the MVC framework picks up that request and runs it through a number of different steps. Somewhere in that pipeline of steps MVC knows that it must call the Initialize method so it finds the Initialize in your MyBaseController class and executes it. At this point all is well and everything works.

When you create a new instance of your HomeController in your test code you're simply creating a new instance of a class. You're not running that class through the MVC request pipeline and you're test framework doesn’t know to execute the Initialize method so you get an error. Personally I would look to test the Index action independently of the Initialize method.

Your Index action above is empty so I can't see exactly what you're trying to do but if you are returning one view for logged in users and another for anonymous users I'd do something like this: TestMethod public void Index_Shows_When_Not_Logged_In(){ HomeController controller = new HomeController(_unitOfWork); controller. CurrentUserId=0; controller.Index(); //Check your view rendered in here } TestMethod public void Some_Other_View_Shows_When_Logged_In(){ HomeController controller = new HomeController(_unitOfWork); controller. CurrentUserId=12; //Could be any value controller.Index(); //Check your view rendered in here } There are some pretty nifty test helpers in the MVC contrib project (http://mvccontrib.codeplex.com/) which allow you to do things like: controller.Index().

AssertViewRendered().

The constructor does not call Initialize. IIRC What calls initialize is the Execute/ExecuteCore method. Here is the code from the MVC source: protected virtual void Execute(RequestContext requestContext) { if (requestContext == null) { throw new ArgumentNullException("requestContext"); } if (requestContext.

HttpContext == null) { throw new ArgumentException(MvcResources. ControllerBase_CannotExecuteWithNullHttpContext, "requestContext"); } VerifyExecuteCalledOnce(); Initialize(requestContext); using (ScopeStorage. CreateTransientScope()) { ExecuteCore(); } } This is basically called from the MvcHandler in the BeginProcessRequest method.

Update: RequestContext does not exist in a unit test, because you're not going through ASP.NET. If I remember correctly you'd need to mock it. Another problem in using Initialize in a test is the membership provider, which I haven't used myself, but I would guess that AccountMembershipService would fail you in a test?

It seems to me that this would create fragile tests. It would probably also slow you down if it has to contact a server, and might fail you on a CI server. IMO,from a basic look around the Init method, it shouldn't be there.

The easiest solution,without breaking anything, that comes to mind is using dependency injection to inject the CurrentUserId in the Controller ctor.

In the case where you "run the actual site" I suspect it calls the default constructor of your HomeController which in turn will call the base controller's correpsonding ctor. Try modifying your custom ctor of public HomeController(IUnitOfWork unitOfWork) to public HomeController(IUnitOfWork unitOfWork):base() This will make sure to call the base controller's default ctor whenever it is called.

There is no default constructor in my HomeController. The only constructor is the one that takes a IUnitOfWork. You cannot call new HomeController() – KallDrexx Mar 31 at 23:27.

When you make a request to a controller through a website the MVC framework picks up that request and runs it through a number of different steps. Somewhere in that pipeline of steps MVC knows that it must call the Initialize method so it finds the Initialize in your MyBaseController class and executes it. At this point all is well and everything works.

The constructor does not call Initialize. IIRC What calls initialize is the Execute/ExecuteCore method.

I cant really gove you an answer,but what I can give you is a way to a solution, that is you have to find the anglde that you relate to or peaks your interest. A good paper is one that people get drawn into because it reaches them ln some way.As for me WW11 to me, I think of the holocaust and the effect it had on the survivors, their families and those who stood by and did nothing until it was too late.

Related Questions