我是这个C#世界的初学者。
有这个模型类:
public class Fund
{
[Required]
public int id { get; set; }
[Required]
public string name { get; set; }
[Required]
public string nickname { get; set; }
}
虽然[Required]
注释遍及所有属性,但实例如:
Fund f = new Fund();
f.name = "test name";
f.nickname = "test ninckname";
总是通过如下测试:
if (ModelState.IsValid)
{
// do stuff
}
我应该如何设置模型,使得这样的实例不会在ModelState.IsValid
测试中传入?
其他情况如:
Fund f1 = new Fund();
f1.id = 3;
f1.nickname = "test ninckname";
和
Fund f2 = new Fund();
f2.id = 3;
f2.name = "test name";
也正在通过测试。
修改
ModelState.IsValid
在控制器内,我正在测试控制器。
编辑2:
这是控制器的方法签名:
[HttpPatch]
public ActionResult EditFund(Fund fund)
编辑3: 这是我的整个测试方法:
[TestMethod]
public void TestEditInvalidFund()
{
// Arrange
FundController controller = new FundController();
controller.ControllerContext = TestModelHelper.AdminControllerContext();
var _fund = new Mock<IFund>();
_fund.SetupGet(f => f.id).Returns(1);
//_fund.SetupGet(f => f.name).Returns("Fund name");
_fund.SetupGet(f => f.nickname).Returns("Fund nickname");
_fund.Setup(f => f.Edit()).Callback(() => {}).Verifiable();
// Act
var result = (JsonResult)controller.EditFund(_fund.Object);
// Assert
SimpleMessage resultMessage = m_serializer.Deserialize<SimpleMessage>(m_serializer.Serialize(result.Data));
Assert.IsNotNull(resultMessage.status, "JSON record does not contain 'status' required property.");
Assert.IsTrue(resultMessage.status.Equals("fail"), "status must be 'fail'");
}
这就是整个控制器的方法:
[HttpPatch]
public ActionResult EditFund(IFund _fund)
{
try
{
if (ModelState.IsValid)
{
//_fund.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.Funds.success_editing_fund, "success");
}
catch (Exception err)
{
return ErrorHelper(@Resources.Global.error, @Resources.Funds.error_editing_fund, err.Message);
}
}
答案 0 :(得分:2)
[Required]
public int id { get; set; }
这将始终有效,因为int不可为空。它的默认值为0.
答案 1 :(得分:2)
您无法对ModelState.IsValid
进行单元测试。好吧,你可以,但你需要额外的代码才能做到这一点,而且它并不完全理想。
这是我在github上的代码:WithModelStateIsInvalid<TController>()
以下是NuGet包:https://www.nuget.org/packages/TestBase-Mvc/
以下是我如何使用它:
UnitUnderTest
.WithModelStateIsInValid()
.Action(model)
.ShouldBeViewResult()
.ShouldBeAnInvalidModel();
-----------------------------------------
您无法对其进行单元测试的原因是模型验证发生在模型绑定步骤之前您的控制器操作被调用。
因此,为了模拟模型验证失败,最简单的方法是在调用操作之前在单元测试代码中手动使controller.ModelState
'无效'。这是扩展方法的作用,但实际上它只是一行:
controller.ModelState.AddModelError("FieldName", @"error message")
(更复杂的扩展方法可能会让您指定哪个模型键无效.PPR总是受欢迎)。
答案 2 :(得分:0)
不确定,为什么它有效,但您可以尝试通过以下方式显式重新验证模型:
TryValidateModel(fund)