当我运行此测试时,我得到一个“Assert.Fail失败.Assert.AreEqual失败。预期:。实际:。”
如果在错误消息末尾没有“Actual:”的情况下通过或未通过此测试?我使用“Assert.Fail(ex.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);
}
}
答案 0 :(得分:4)
嗯,据我所知,你想为你的断言指定自定义失败消息吗?
行,
Assert.AreEqual( object expected, object actual, string message );
更多here
您甚至可以创建一些特殊失败断言,请在此处阅读CustomAsserts
IMO,你不需要那个try-catch块,只需在你的断言中添加自定义消息
答案 1 :(得分:3)
添加了其他信息:单元测试(一般情况下)只应检查单个组件。对于这个测试,我会删除验证用户的调用,因为它应该是它自己的检查它自己的测试方法。
这意味着两种测试方法
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 Methods正在做一些与此类似的事情(虽然可能在内部抛出派生的Exception类型而不是基类)。
作为高级别建议,我会说对提供商进行单元测试将非常困难。我过去创建了一个自定义的,以一种允许我控制输入和输出的方式重写它是一场噩梦。我必须做的是提供一个构造函数,它允许我为我的外部依赖项传递接口,以允许我编写我的测试。当我这样做然后我能够编写诸如
之类的测试 ReturnsCreatedUser_IfCreationIsSuccessful()
或ReturnsInvalidPassword_IfPasswordIsInvalid()
断言看起来像这样:Assert.AreEqual(MembershipCreateStatus.Success, _status);
Assert.IsNotNull(response);
,
和
Assert.AreEqual(MembershipCreateStatus.InvalidPassword, _status);
。
这是您在尝试测试提供程序时遇到的第二个问题。现在,使用您想要的消息抛出异常将允许您完全自定义消息。
答案 2 :(得分:1)
“实际”来自ex.Message。 This is read-only。
你可以做一些字符串操作,例如:
catch (Exception ex)
{
string message = ex.Message.Substring(0, ex.Message.IndexOf("Actual:"));
LogMessage(message);
Asset.Fail(ex.Message);
}