C# 如何更改Assert.Fail消息
运行此测试时,我得到一个“Assert.Fail failed.Assert.AreEqual failed.Expected:。实际:” 如何在错误消息末尾不显示“Actual:”而通过或失败该测试?我在其他几个测试中使用了“Assert.Fail(ex.Message);”,因此无法直接更改消息C# 如何更改Assert.Fail消息,c#,visual-studio-2010,unit-testing,C#,Visual Studio 2010,Unit Testing,运行此测试时,我得到一个“Assert.Fail failed.Assert.AreEqual failed.Expected:。实际:” 如何在错误消息末尾不显示“Actual:”而通过或失败该测试?我在其他几个测试中使用了“Assert.Fail(ex.Message);”,因此无法直接更改消息 [TestMethod] public void TestCreateUser() { try { AsaMembership
[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);
}
}
那么,据我所知,您想为您的断言指定自定义失败消息吗 嗯 更多 您甚至可以创建一些特殊的失败断言,请阅读这里的 依我看,您不需要try-catch块,只需将自定义消息添加到您的断言中即可“实际”消息来自ex.Message 您可以执行一些字符串操作,例如:
catch (Exception ex)
{
string message = ex.Message.Substring(0, ex.Message.IndexOf("Actual:"));
LogMessage(message);
Asset.Fail(ex.Message);
}
添加的附加信息:单元测试(通常)应仅检查单个组件。对于这个测试,我将删除验证用户的调用,因为它应该是它自己的签入测试方法 这意味着两种测试方法
CreateUser\u IsSuccessful\u如果CreatingUserThat DoesNotExist()
ValidateUser\u验证\u如果给定正确的用户名和密码()
它比TestCreateUser方法名更具描述性,并允许您进行更细粒度的测试。然后,下一个测试可能是CreateUser\u failures\u如果creatingexistinguser()
很难给出真正好的建议,因为我们不知道您正在进行的项目的要求。如果你必须有定制的输出,那么我最初的建议会起作用(但这不是一个最佳实践,我觉得有点像黑客)。更好的解决方案是这样的:
[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.");
}
[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
}
它自定义了错误消息并删除了不必要的笨重的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()
{
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.");
}
[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方法在内部执行与此非常类似的操作(尽管可能会抛出派生异常类型而不是基异常)
作为高级建议,我要说的是,对提供者进行单元测试将非常困难。我在过去创建了一个自定义的,以允许我控制输入和输出的方式重写它是一个噩梦。我需要做的是提供一个构造函数,它允许我为外部依赖项传递接口,从而允许我编写测试。当我这样做的时候,我就能够编写测试,比如
ReturnsCreatedUser\u如果创建成功()
或ReturnsInvalidPassword\u如果密码无效()
断言如下:Assert.AreEqual(MembershipCreateStatus.Success,_status);
Assert.IsNotNull(响应)代码>,
及
Assert.AreEqual(MembershipCreateStatus.InvalidPassword,_status)代码>
这是您在尝试测试提供程序时遇到的第二个问题。目前,抛出所需消息的异常将允许您完全自定义消息。您刚才不是问了这个问题吗?其他资产通过了吗?如果您看到Assert.Fail(例如Message)的值代码>您将看到“实际”和“预期”,因为您正在断言中传递ex.Message
属性。实际代码应引发异常(应由tets检查),而不是测试。测试应该验证行为。尽管这种方法有助于更改异常消息,但根本不应该有try/catch。从单元测试的角度来看,这是完全错误的。我不同意你的观点。本着stackoverflow的精神,我不确定是应该直接删除答案,还是在答案回答问题时保留它。我将编辑我的答案,以提供更好的指导,因为它一直困扰着我。谢谢你的建设性评论。@taras.roshko我根据你的反馈编辑了我的答案。希望它比以前更好。谢谢你的更新。我应该补充一点,如果您想验证预期的异常,使用Assert.Throws会更好,编写Assert.AreEqual(“name”,userName,“User name mismatch”)显然更干净;而不是试图用if+Assert.faily来归档这种行为,这也是MSTest再次让我失望的地方。努尼特总是有更好的办法。