DynamicMock and expected # 1, valid # 0

I think I donโ€™t understand something in Mock, if I use DynamicMock, it should only check the one that I expect, right? Why am I getting an exception in my test? I do not want to verify that the session is established, I only want to verify that calling _authService.EmailIsUnique is calling the correct parameters. My problem is that in my AdminController I installed _authService.Session ...

private MockRepository _mock; private ISession _session; private IAuthenticationService _authService; private AdminController _controller; private TestControllerBuilder _builder; [SetUp] public void Setup() { _mock = new MockRepository(); _session = _mock.DynamicMock<ISession>(); _authService = _mock.DynamicMock<IAuthenticationService>(); _controller = new AdminController(_authService, _session); _builder = new TestControllerBuilder(); _builder.InitializeController(_controller); } [Test] public void Register_Post_AddModelErrorWhenEmailNotUnique() { var userInfo = new RegisterModel(); userInfo.Email = " the_email@domain.com "; //_authService.Expect(x => x.Session = _session).Repeat.Once(); Expect.Call(_authService.EmailIsUnique(userInfo.Email)).Repeat.Once().Return(false); _mock.ReplayAll(); var result = _controller.Register(userInfo); var viewResult = (ViewResult)result; _authService.VerifyAllExpectations(); result.AssertViewRendered().ForView("").WithViewData<RegisterModel>(); Assert.That(viewResult.ViewData.Model, Is.EqualTo(userInfo)); } 

Rhino.Mocks.Exceptions.ExpectationViolationException: IAuthenticationService.set_Session (ISessionProxy2f2f623898f34cbeacf2385bc9ec641f); Expected # 1, actual # 0.

Thanks for the help!

Update

This is part of my controller and my AuthService ... I use Ninject as DI, since my AuthService is in my domain and Ninject is in my WebApp. I do not know how I could use DI in my AuthService to solve my session. Thanks again!

  public partial class AdminController : Controller { private IAuthenticationService _authService; private ISession _session; public AdminController(IAuthenticationService authService, ISession session) { _authService = authService; _authService.Session = session; _session = session; } [HttpPost] [Authorize(Roles = "Admin")] [ValidateAntiForgeryToken] public virtual ActionResult Register(RegisterModel userInfo) { if (!_authService.EmailIsUnique(userInfo.Email)) ModelState.AddModelError("Email", Strings.EmailMustBeUnique); if (ModelState.IsValid) { return RegisterUser(userInfo); } return View(userInfo); } private RedirectToRouteResult RegisterUser(RegisterModel userInfo) { _authService.RegisterAdmin(userInfo.Email, userInfo.Password); var authToken = _authService.ForceLogin(userInfo.Email); SetAuthCookie(userInfo.Email, authToken); return RedirectToAction(MVC.Auction.Index()); } } public class AuthenticationService : IAuthenticationService { public ISession Session { get; set; } public bool EmailIsUnique(string email) { var user = Session.Single<User>(u => u.Email == email); return user == null; } } 
+4
source share
1 answer

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() { // arrange var userInfo = new RegisterModel(); userInfo.Email = " the_email@domain.com "; _authService .Stub(x => x.EmailIsUnique(userInfo.Email)) .Return(false); // act var actual = _controller.Register(userInfo); // assert actual .AssertViewRendered() .WithViewData<RegisterModel>() .ShouldEqual(userInfo, ""); Assert.IsFalse(_controller.ModelState.IsValid); } 

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:

 /// <summary> /// Load your modules or register your services here! /// </summary> /// <param name="kernel">The kernel.</param> private static void RegisterServices(IKernel kernel) { kernel.Bind<ISession>().To<SessionImpl>(); kernel.Bind<IAuthenticationService>().To<AuthenticationService>(); } 
+2
source

Source: https://habr.com/ru/post/1346251/


All Articles