![](/img/trans.png)
[英]How to write unit test for asynchronous (socket) code that includes ManualResetEvent.WaitOne()?
[英]How to unit test code that includes a database transaction
如何將單位放在以下代碼周圍:
public DbContextTransaction QTTransactionBegin()
{
return Database.BeginTransaction();
}
public int CreateCampaign(CreateCampaignModel createCampaignModel)
{
using (var transaction = _qtContext.QTTransactionBegin())
{
try
{
var campaign = new Campaign();
campaign.CampaignCode = createCampaignModel.CampaignCode;
campaign.CampaignDescription = createCampaignModel.CampaignDescription;
campaign.CampaignDate = createCampaignModel.CampaignDate;
campaign.CampaignNotes = createCampaignModel.CampaignNotes;
campaign.OwnerUserID = createCampaignModel.OwnerUserID;
campaign.AddedOn = DateTime.Now;
campaign.AddedBy = createCampaignModel.OwnerUserName;
campaign.UpdatedOn = DateTime.Now;
campaign.UpdatedBy = createCampaignModel.OwnerUserName;
campaign.CampaignSegments = GetCampaignSegmentList(createCampaignModel);
var campaignId = AddOrUpdateCampaign(campaign);
transaction.Commit();
return campaignId;
}
catch (Exception ex)
{
transaction.Rollback();
}
}
return 0;
}
誰能告訴我如何在上面的代碼周圍進行單元測試?
我嘗試了如下代碼:
Database_database;
[TestInitialize]
public void SetUp()
{
_qtDALMock = _factory.CreateMock<IQTDAL>();
_campaignRepository = new CampaignRepository(_qtDALMock.MockObject);
}
[TestMethod]
public void Check_CreateCampaign_Test()
{
// arrange
const int expectedCampaignId = 1;
var createCampaign = QueryToolDummies.CreateCampaignModel;
_database.BeginTransaction();
_qtDALMock.Expects.One.MethodWith(x => x.QTTransactionBegin())
.WillReturn(_database.BeginTransaction());
_qtDALMock.Expects.One.Method(x => x.AddOrUpdateCampaign(null))
.With(Is.TypeOf<Campaign>())
.WillReturn(expectedCampaignId);
// act
var result = _campaignRepository.CreateCampaign(createCampaign);
// assert
Assert.IsNotNull(result);
}
這個_database.BeginTransaction()
有問題。 錯誤說不能像這樣使用。
請指教。
一個問題? 為什么要嘗試將事務啟動到單元測試中?
如果您使用Moq framework
模擬您的存儲庫並返回您需要從存儲庫返回的內容,那將會很容易。
事實上,我認為在單元測試中啟動一個BeginTransaction()
並不是一個好習慣。
我希望這有幫助
我遇到了同樣的問題,解決起來非常棘手。
我嘗試為公開BeginTransaction()
方法的上下文創建一個包裝類,但最終您最終需要在測試時模擬BeginTransaction()
返回的DbContextTransaction
,但DbContextTransaction
既沒有接口也沒有公共構造函數。
最后我寫了一個事務管理器類,它創建和管理自己的事務,並公開開始、提交和回滾事務的方法。 然后可以偽造該管理器類以及返回它的服務,從而允許對使用事務的代碼進行全面測試。
我已經在這個答案中完整地寫了。
您正在嘗試對多個單元進行單元測試。
假設上面的代碼是您的“數據層”/存儲庫,那么您正在執行集成測試,因為測試中涉及的單元不止一個。
您可以在測試類中包含數據庫的設置/拆卸,並使用有效和無效數據調用 SUT(被測對象)以驗證預期行為。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.