Тестирование определенных вызовов методов с параметрами с использованием Moq
Я пытаюсь написать модульный тест с Moq, чтобы убедиться, что регистрация прошла успешно. Мой тест выглядит следующим образом:
[TestMethod()]
public void RegisterTest()
{
//Arrange
var MockRepo = new Mock<IDataRepo>() ;
RegisterModel model = new RegisterModel
{
ConfirmPassword = "SamePassword",
Email = "myemail@address.com",
FirstName = "MyFirstName",
LastName = "MyLastName",
MiddleName = "MyMiddleName",
Password = "SamePassword"
};
MockRepo.Setup(ctx => ctx.Add(model)).Verifiable("Nothing was added to the Database");
//Act
AccountController target = new AccountController(MockRepo.Object);
//Assert
ActionResult actual = target.Register(model);
MockRepo.Verify(ctx => ctx.Add(It.IsAny<RegisterModel>()));
Assert.IsInstanceOfType(actual, typeof(ViewResult));
}
Но это терпит неудачу со следующей ошибкой
Ожидаемый вызов на макет хотя бы один раз, но так и не был выполнен: ctx => ctx.Add(It.IsAny())
Однако, когда я отлаживал Test Method, я заметил, что метод Add(T) был фактически вызван. Версия MOQ dll v4.0
ОБНОВЛЕНИЕ контроллера аккаунта:
public class AccountController : Controller
{
private IDataRepo _repo;
public AccountController(IDataRepo Repo)
{
_repo = Repo;
}
public ActionResult Register(RegisterModel model)
{
if (ModelState.IsValid)
{
User user = _repo.Users.Where(u => u.Email == model.Email).FirstOrDefault();
if (user == null)
{
_repo.Add(new User
{
Email = model.Email,
Password = model.Password,
FirstName = model.FirstName,
LastName = model.LastName,
MiddleName = model.MiddleName
});
return View("RegistrationSuccess");
}
else
{
ModelState.AddModelError("UserExists", "This Email already Exists");
}
}
return View(model);
}
}
2 ответа
Решение
Ваша проблема в том, что ваш макет ожидает RegisterModel
пример
RegisterModel model = new RegisterModel
{
ConfirmPassword = "SamePassword",
Email = "myemail@address.com",
FirstName = "MyFirstName",
LastName = "MyLastName",
MiddleName = "MyMiddleName",
Password = "SamePassword"
};
MockRepo.Setup(ctx => ctx.Add(model))
но Add
метод вызывается с экземпляром User
учебный класс
_repo.Add(new User
{
Email = model.Email,
Password = model.Password,
FirstName = model.FirstName,
LastName = model.LastName,
MiddleName = model.MiddleName
});
Таким образом, один из способов обойти это, чтобы настроить макет, чтобы принять User
пример.
RegisterModel model = new RegisterModel
{
ConfirmPassword = "SamePassword",
Email = "myemail@address.com",
FirstName = "MyFirstName",
LastName = "MyLastName",
MiddleName = "MyMiddleName",
Password = "SamePassword"
};
User expected = new User
{
Email = model.Email,
Password = model.Password,
FirstName = model.FirstName,
LastName = model.LastName,
MiddleName = model.MiddleName
};
MockRepo.Setup(ctx => ctx.Add(expected))
Я обнаружил более простой способ сделать это. Вместо того, чтобы генерировать свой собственный объект User, вы можете вызвать It.IsAny<User>()
и тест будет работать нормально. так что мой тестовый модуль теперь становится..
//Arrange
var MockRepo = new Mock<IDataRepo>() ;
var MockMembership = new Mock<IMembership>();
RegisterModel model = new RegisterModel
{
ConfirmPassword = "SamePassword",
Email = "myemail@address.com",
FirstName = "MyFirstName",
LastName = "MyLastName",
MiddleName = "MyMiddleName",
Password = "SamePassword"
};
MockRepo.Setup(ctx => ctx.Add(It.IsAny<User>())).Verifiable("Nothing was added to the Database");
//Act
AccountController target = new AccountController(MockRepo.Object, MockMembership.Object);
//Assert
ActionResult actual = target.Register(model);
MockRepo.Verify(ctx => ctx.Add(It.IsAny<User>()));
Assert.IsInstanceOfType(actual, typeof(ViewResult));