views:

116

answers:

2

I got this error on my unit test:

Assert.AreEqual failed. Expected:<ShizoMe.Web.ViewModel.AccountViewModel>. Actual:<ShizoMe.Web.ViewModel.AccountViewModel>. 

This is the code for my test:

[TestMethod]
    public void Register_Prevents_Duplicate_Users()
    {
        var controller = GetAccountController();

        var model = new AccountViewModel
                        {
                            Register = new RegisterModel
                                           {
                                               EmailAddress = "[email protected]"
                                           }
                        };

        var result = (ViewResult) controller.Register(model.Register);
        Assert.AreEqual("A user with this email address already exists.",
            controller.ModelState["UserExists"].Errors[0].ErrorMessage);
        Assert.AreEqual(model, result.ViewData.Model);
    }

This is my Register method:

[HttpPost]
    public virtual ActionResult Register([Bind(Prefix = "Register")]RegisterModel model)
    {
        var accountModel = new AccountViewModel();

        if (ModelState.IsValid)
        {
            if (_accountRepository.GetUser(model.EmailAddress) != null)
            {
                ModelState.AddModelError("UserExists", "A user with this email address already exists.");
                return View(accountModel);
            }

            var newUser = new User
                              {
                                  EmailAddress = model.EmailAddress,
                                  Password = model.Password,
                                  CreatedDate = DateTime.UtcNow
                              };

            if (_accountRepository.RegisterUser(newUser))
            {
                _formsService.SignIn(newUser);
                return RedirectToAction(MVC.Home.Index());
            }
        }

        return View(accountModel);
    }

Any idea why the last Assert.AreEqual failed? When I debug, the ViewModels (model and result.ViewData.Model) are the same.

Thank you very much.

A: 

Is AccountViewModel IEquatable? If not, C# will just use Object.ReferenceEquals to compare them. That will only be true if they both reference to the exactly same object (have the same property values is not good enough).

James Curran
+1  A: 

Did you override the Equals() and GetHashCode() methods for your AccountViewModel class?

example:

public override bool Equals(object obj)
    {
        if (obj == null)
        {
            return false;
        }

        if (Object.ReferenceEquals(this, obj))
        {
            return true;
        }

        if (this.GetHashCode() == obj.GetHashCode())
        {
            return true;
        }

        return false;
    }

    public override int GetHashCode()
    {
        return Id.GetHashCode();
    }
Jonathan Bates
Hi Jonathan, can you give me an example or points me to a link about overriding Equals() and GetHashCode() methods? I have no idea what I need to do :) Thanks a lot.
Xuan Vu
This is what i'm having right now, which doesn't seems to work: public override bool Equals(object obj) { if (obj == this) return true; var that = obj as AccountViewModel; return that != null } public override int GetHashCode() { return base.GetHashCode(); }Thanks.
Xuan Vu
You need to decide what equality is for your object. I try to pick a property that represents identity for an entity. I would then return the hash code of that property in the GetHashCode() override and override Equals(), referencing GetHashCode() from within that method - answer editted with sample. Its a basic framework to start with. In your case, you may want to start with the nested User object, using the EmailAddress property. And in the Account model could be based off of the internal user object. In this was you'd compare the features you want and not object references.
Jonathan Bates