如何对包含数据库事务的代码进行单元测试

本文关键字:代码 单元测试 事务 包含 数据库 | 更新日期: 2023-09-27 17:50:11

如何在下列代码周围放置单位:

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()有问题。错误提示不能像它那样使用

请建议。

如何对包含数据库事务的代码进行单元测试

我也遇到过同样的问题,很难解决。

我尝试为暴露BeginTransaction()方法的上下文创建包装器类,但最终您需要在测试时模拟BeginTransaction()返回的DbContextTransaction,但DbContextTransaction既没有接口也没有公共构造函数。

最后,我编写了一个事务管理器类,它创建和管理自己的事务,并公开了开始、提交和回滚事务的方法。然后,可以伪造该管理器类和返回它的服务,从而允许使用事务的代码进行全面测试。

我已经在这个答案中详细地写了。

您正在尝试对多个单元进行单元测试。

假设上面的代码是您的"数据层"/存储库,那么您正在执行集成测试,因为测试中涉及到多个单元。

您可以在您的测试类中包含数据库的setup/teardown,并使用有效和无效的数据调用SUT(被测主题)来验证预期的行为。

有问题吗?为什么要尝试将事务启动为单元测试?

如果您使用Moq framework模拟您的存储库并返回您需要从repo返回的内容,那么

将很容易。

事实上,我认为在单元测试中启动BeginTransaction()不是一个好的实践。

希望对大家有所帮助