附加信息添加:单元测试(一般来说)只能检查单个组件。对于这个测试,我会删除调用来验证用户,因为它应该是它自己的检查它自己的测试方法。
这意味着两种试验方法 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", "[email protected]", "", "", 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, "[email protected]");
if (user.Email != "[email protected]")
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
{
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", "[email protected]", "", "", 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, "[email protected]");
if (user.Email != "[email protected]")
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);
。
这是您尝试测试提供程序时遇到的第二个问题。现在,用你想要的信息抛出异常将允许你完全自定义你的信息。
你刚才问这个吗?其他断言是否通过?如果你看到'Assert.Fail(ex.Message)'的值;''你将会看到'Actual'和'Expected',因为你在断言中传递了'ex.Message'属性。 – Brian 2013-05-13 18:18:45