如何更改断言失败消息

本文关键字:消息 失败 断言 何更改 | 更新日期: 2023-09-27 18:13:25

当我运行此测试时,我得到一个"Assert.Fail failed.Assert.AreEqual failed.预期:.实际:.">

如果错误消息末尾没有"Actual:",我该如何使此测试通过或失败?我在其他几个测试中使用了"断言失败(e.Message(;",所以我不能直接更改消息。

    [TestMethod]
    public void TestCreateUser()
    {
       try
       {
          AsaMembershipProvider prov = this.GetMembershipProvider();
          //call get user
          MembershipCreateStatus status;
          MembershipUser user = prov.CreateUser("testUserX", "12345", "test.UserX@abc.com", "", "", true, null, out status);
          Assert.AreNotEqual(status, MembershipCreateStatus.Success);
          var isAuthenticated = prov.ValidateUser(user.UserName, "12345");
          Assert.IsTrue(isAuthenticated);
          Assert.AreEqual(user.UserName, "testUserX");
          Assert.AreEqual(user.Email, "test.userx@abc.com");
          Assert.IsTrue(user.CreationDate==DateTime.Now);
          //TODO Asserts
       }
       catch (Exception ex)
       {
          LogMessage(ex);
          Assert.Fail(ex.Message);
       }
    }

如何更改断言失败消息

好吧,据我所知,您想为断言指定自定义失败消息吗?

好的,

Assert.AreEqual( object expected, object actual, string message );

点击此处了解更多

您甚至可以创建一些特殊失败断言,请阅读此处有关CustomAsserts 的信息

IMO,您不需要try-catch块,只需将自定义消息添加到您的断言

添加的附加信息:单元测试(通常(应该只检查单个组件。对于这个测试,我将删除验证用户的调用,因为它应该是它自己在自己的测试方法中的检查。

这意味着有两种测试方法CreateUser_IsSuccessful_IfCreatingUserThatDoesNotExist()ValidateUser_Authenticates_IfGivenCorrectUsernameAndPassword()

它比TestCreateUser方法名称更具描述性,并允许您进行更细粒度的测试。下一个测试可以是CreateUser_Fails_IfRecreatingExistingUser()

很难给出真正好的建议,因为我们不知道你正在进行的项目的要求。如果你必须有定制的输出,那么我最初提出的建议会奏效(但这不是最佳实践,对我来说有点像黑客(。更好的解决方案是这样的:

[TestMethod]
public void TestCreateUser()
{
    AsaMembershipProvider prov = this.GetMembershipProvider();
    //call get user
    MembershipCreateStatus status;
    MembershipUser user = prov.CreateUser("testUserX", "12345", "test.UserX@abc.com", "", "", true, null, out status);
    //Assert.AreNotEqual(status, MembershipCreateStatus.Success);
    if (status != MembershipCreateStatus.Success)
        Assert.Fail("Error message you want goes here for this case.");
    var isAuthenticated = prov.ValidateUser(user.UserName, "12345");
    //Assert.IsTrue(isAuthenticated);
    if (!isAuthenticated)
        Assert.Fail("Error message you want goes here for this case.");
    //Assert.AreEqual(user.UserName, "testUserX");
    if (user.UserName != "testUserX")
        Assert.Fail("Error message you want goes here for this case.");
    //Assert.AreEqual(user.Email, "test.userx@abc.com");
    if (user.Email != "test.userx@abc.com")
        Assert.Fail("Error message you want goes here for this case.");
    //Assert.IsTrue(user.CreationDate==DateTime.Now);
    if (user.CreationDate != DateTime.Now)
        Assert.Fail("Error message you want goes here for this case.");
}

它自定义了错误消息,并删除了不必要的笨拙的try-catch。

由于答案被接受,我将保留以前的原始输出,但我同意try-catch不应以这种方式使用的评论(因此进行了上述更正(。我在测试中使用try-catch的唯一一次是,如果我专门测试一个场景,即如果违反业务规则,就会引发特定类型的异常

try
{
    methodToThrowException();
    Assert.Fail("BusinessSpecificException was not thrown by the code.");
}
catch (BusinessSpecificException ex)
{
    //Asserts go here
}

如果你想将所有断言集中到catch块,并且你想自定义错误输出,可以这样实现:

    [TestMethod]
    public void TestCreateUser()
    {
       try
       {
          AsaMembershipProvider prov = this.GetMembershipProvider();
          //call get user
          MembershipCreateStatus status;
          MembershipUser user = prov.CreateUser("testUserX", "12345", "test.UserX@abc.com", "", "", true, null, out status);
          //Assert.AreNotEqual(status, MembershipCreateStatus.Success);
          if (status != MembershipCreateStatus.Success)
              throw new Exception("Error message you want goes here for this case.");
          var isAuthenticated = prov.ValidateUser(user.UserName, "12345");
          //Assert.IsTrue(isAuthenticated);
          if (!isAuthenticated)
              throw new Exception("Error message you want goes here for this case.");
          //Assert.AreEqual(user.UserName, "testUserX");
          if (user.UserName != "testUserX")
              throw new Exception("Error message you want goes here for this case.");
          //Assert.AreEqual(user.Email, "test.userx@abc.com");
          if (user.Email != "test.userx@abc.com")
              throw new Exception("Error message you want goes here for this case.");
          //Assert.IsTrue(user.CreationDate==DateTime.Now);
          if (user.CreationDate != DateTime.Now)
              throw new Exception("Error message you want goes here for this case.");
          //TODO Asserts
       }

并且您的测试方法仍将运行Assert.Fail部分。幕后的Assert方法在内部执行与此非常类似的操作(尽管可能会抛出派生的Exception类型而不是基类型(。

作为高级建议,我会说,单元测试的提供者将非常困难。我过去创建过一个自定义的,以允许我控制输入和输出的方式重写它是一场噩梦。我所要做的是提供一个构造函数,它允许我为外部依赖项传递接口,从而允许我编写测试。当我这样做的时候,我就可以写之类的测试了

ReturnsCreatedUser_IfCreationIsSuccessful()ReturnsInvalidPassword_IfPasswordIsInvalid()

断言看起来像这样:Assert.AreEqual(MembershipCreateStatus.Success, _status); Assert.IsNotNull(response);

Assert.AreEqual(MembershipCreateStatus.InvalidPassword, _status);

这是在尝试测试提供程序时会遇到的次要问题。现在,在您想要的消息中抛出异常将允许您完全自定义消息。

"Actual"来自ex.Message。这是只读的。

不过,你可以做一些字符串操作,比如:

catch (Exception ex)
{
    string message = ex.Message.Substring(0, ex.Message.IndexOf("Actual:"));
    LogMessage(message);
    Asset.Fail(ex.Message);
}