У меня есть этот метод внутри контроллера:C# MVC Мок модель через интерфейс контроллер файлов нарушает
[HttpPatch]
[AllowAdminOnly]
public JsonResult EditUser(User _user)
{
try
{
if (ModelState.IsValid)
{
_user.Edit();
}
else
{
string error_messages = "";
foreach (var e in ModelState.Select(x => x.Value.Errors).Where(y => y.Count > 0).ToList())
{
error_messages += e[0].ErrorMessage + "\n";
}
throw new Exception(error_messages);
}
return MessageHelper(@Resources.Global.success, @Resources.Users.success_editing_user, "success");
}
catch (Exception err)
{
return ErrorHelper(@Resources.Global.error, @Resources.Users.error_editing_user, err.Message);
}
}
Для модульного тестирования этого метода, я нашел ссылки (...) говорили, что я должен " макет "_user.Edit();
. Кажется, это хорошо, это позволит избежать сохранения данных в базе данных и ускорит тесты.
Мой тест затем (для действительного пользователя) становится:
[TestMethod]
public void UserController_EditUser_Valid()
{
// Arrange
FundController controller = new UserController();
controller.ControllerContext = TestModelHelper.AdminControllerContext();
var _user = new Mock<Fund>();
_user.SetupGet(f => f.id).Returns(1);
_user.SetupGet(f => f.name).Returns("User name");
_user.SetupGet(f => f.nickname).Returns("User nickname");
_user.SetupGet(f => f.active).Returns(true);
_user.Setup(f => f.Edit()).Callback(() => {}).Verifiable();
// Act
var result = (JsonResult)controller.EditUser(_user.Object);
SimpleMessage resultMessage = m_serializer.Deserialize<SimpleMessage>(m_serializer.Serialize(result.Data));
// Assert
Assert.IsNotNull(resultMessage, "Result must not be null");
Assert.IsTrue(resultMessage.status.Equals("success"), "status must be 'success'");
}
Но когда я это делаю, я получаю следующее сообщение об ошибке:
Test Name: UserController_EditUser_Valid
Test FullName: Pmanager.Tests.Controllers.UserControllerTest.UserController_EditUser_Valid
Test Source: ...\Pmanager\Pmanager.Tests\Controllers\UserControllerTest.cs : line 95
Test Outcome: Failed
Test Duration: 0:00:00,0179908
Result StackTrace:
em Moq.Mock.ThrowIfCantOverride(Expression setup, MethodInfo method)
em Moq.Mock.<>c__DisplayClass66_0`2.<SetupGet>b__0()
em Moq.PexProtector.Invoke[T](Func`1 function)
em Moq.Mock.SetupGet[T,TProperty](Mock`1 mock, Expression`1 expression, Condition condition)
em Moq.Mock`1.SetupGet[TProperty](Expression`1 expression)
em Pmanager.Tests.Controllers.UserControllerTest.UserController_EditUser_Valid() na ...\Pmanager\Pmanager.Tests\Controllers\UserControllerTest.cs:linha 100
Result Message:
Test method Pmanager.Tests.Controllers.UserControllerTest.UserController_EditUser_Valid threw exception:
System.NotSupportedException: Valid setup on a non-virtual (overridable in VB) member: f => f.id
Я нашел документацию (...), говоря, что я должен использовать интерфейс вместо класса при создании «mock».
Итак, я создал интерфейс:
public interface IUser
{
int id { get; set; }
string name { get; set; }
string nickname { get; set; }
bool active { get; set; }
void Edit();
}
, а затем я изменил все для IUser
, контроллера метод подписи:
public JsonResult EditUser(IUser _user);
тест "фиктивный" декларация:
var _user = new Mock<IUser>();
и так далее.
Теперь тест работает, но метод фактического контроллера для редактирования пользователя не работает!
Как я могу собрать все эти вещи, не нарушая функциональность контроллера trully?
'вар _user = новый Mock()' или 'вар _user = новый Mock ();' –
Shyju
'вар _user = новый Mock();', извините –
вы передаете макет реализации от IUser. так что вам также нужно обеспечить макетную реализацию Edit! Ваше существующее Редактирование не будет работать. Вы ожидали этого? – Shyju