附加信息添加:單元測試(一般來說)只能檢查單個組件。對於這個測試,我會刪除調用來驗證用戶,因爲它應該是它自己的檢查它自己的測試方法。
這意味着兩種試驗方法 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