My problem is that in my AdminController I set _authService.Session
Yes, this is really a problem, as it depends on your DI infrastructure, not your controller code. Therefore, if ISession is not directly used by the controller, it must be removed from it. The controller should not perform any plumbing work between the service and any dependencies of this service.
So here is an example:
public class AdminController : Controller { private readonly IAuthenticationService _authService; public AdminController(IAuthenticationService authService) { _authService = authService; } public ActionResult Register(RegisterModel userInfo) { if (!_authService.EmailIsUnique(userInfo.Email)) { ModelState.AddModelError("Email", Strings.EmailMustBeUnique); return View(userInfo); } return RedirectToAction("Success"); } }
Note that the administrator controller should not rely on any session. It already relies on IAuthenticationService . The way this service is implemented is not important. And in this case, the correct unit test would be:
private IAuthenticationService _authService; private AdminController _controller; private TestControllerBuilder _builder; Setup() { _authService = MockRepository.GenerateStub<IAuthenticationService>(); _controller = new AdminController(_authService); _builder = new TestControllerBuilder(); _builder.InitializeController(_controller); } [Test] public void Register_Post_AddModelErrorWhenEmailNotUnique() {
UPDATE:
Now that you have shown your code, I confirm:
Remove the ISession dependency from your controller as it is not needed, and leave this job as part of the DI.
Now I see that your AuthenticationService is heavily dependent on ISession, so the installation of the constructor will be more adapted, rather than nesting properties. Use property injection only for additional dependencies:
public class AuthenticationService : IAuthenticationService { private readonly ISession _session; public AuthenticationService(ISession session) { _session = session; } public bool EmailIsUnique(string email) { var user = _session.Single<User>(u => u.Email == email); return user == null; } }
and the last remaining part is plumbing. This is done in an ASP.NET MVC application that has links to all other layers. And since you mentioned Ninject, you can install Nuject.MVC3 NuGet and in the generated ~/App_Start/NinjectMVC3 just configure the kernel: