我有一個應用程序服務(即大型方法)負責協調多個業務對象之間的交互。從本質上說,它需要一個包含客戶信息和發票的系統的DTO,並根據各種業務規則將其翻譯並導入到不同的系統中。正確處理單元測試「複雜」應用程序服務
public void ProcessQueuedData()
{
var queuedItems = _importServiceDAL.LoadQueuedData();
foreach (var queuedItem in queuedItems)
{
var itemType = GetQueuedImportItemType(queuedItem);
if (itemType == QueuedImportItemType.Invoice)
{
var account = _accountDAL.GetAccountByAssocNo(queuedItem.Assoc);
int agentAccountID;
if (!account.IsValid)
{
agentAccountId = _accountDAL.AddAccount(queuedItem.Assoc);
}
else
{
agentAccountId = account.AgentAccountID;
}
/// Do additional processing TBD
}
}
}
對於單元測試,它是正確的假設的服務內的整個過程中應在粒狀步步基礎進行測試,類似於以下?
ImportService_ProcessQueuedData_CallsDataAccessLayer_ToLoadQueue
ImportService_ProcessQueuedData_WithQueuedItemToProccess_ChecksIfAccountExists
ImportService_ProcessQueuedData_WithInvoice_CallsDALToCreateAccountIfOneDoesNotExist
下面是一個典型的測試:
[TestMethod()]
public void ImportService_ProcessQueuedData_WithInvoice_CallsDALToCheckIfAgentAccountExists()
{
var accountDAL = MockRepository.GenerateStub<IAccountDAL>();
var importServiceDAL = MockRepository.GenerateStub<IImportServiceDAL>();
importServiceDAL.Stub(x => x.LoadQueuedData())
.Return(GetQueuedImportItemsWithInvoice());
accountDAL.Stub(x => x.GetAccountByAssocNo("FFFFF"))
.IgnoreArguments()
.Return(new Account() { AgentAccountId = 0 });
var importSvc = new ImportService(accountDAL, importServiceDAL);
importSvc.ProcessQueuedData();
accountDAL.AssertWasCalled(a => a.GetAccountByAssocNo("FFFFF"), o => o.IgnoreArguments());
accountDAL.VerifyAllExpectations();
}
我的問題是我最終在這些測試中做了這麼多設置,它變得很脆弱。這是否是正確的方法,如果是的話,在每個粒度測試中避免重複所有這些設置的指針是什麼?
謝謝吉安...你建議NModel B/C可能的輸入條件的感知數量是巨大的?如果輸入類型的組合更受限制,您是否仍然會推薦這種方法?我試圖測試的整個過程實際上只有6個條件分支和已知數量的條件在這個if-then邏輯中發揮作用。再次感謝您的洞察力。 – nerdn 2010-07-22 12:44:40
它更像是一個連續的過程,在每一步都有可能出現錯誤情況,並且可能有通過這些行爲的多種不同途徑。這就是基於模型的測試真正閃耀的地方 - 您只需對模型中的所有狀態進行編碼,並讓測試系統找出可能的路徑。 – Gian 2010-07-22 13:02:11