应用程序层单元测试在DDD中的外观如何?

达布尔斯基斯

在我的工作中,我们正在编写由应用程序调用的Web服务。我们正在使用域驱动设计以敏捷的思维方式进行工作。与DDD中一样,我们具有域和应用程序层。但是,在为这些层编写单元测试时,我们遇到了问题,因为似乎我们在域单元测试和应用程序单元测试中两次测试了域逻辑:

应用单元测试

    [TestMethod]
    public void UserApplicationService_SignOut_ForExistingUserWithBalance_ShouldClearBalanceAndSignOut()
    {
        //Arrange
        long merchantId = 1;
        long userId = 1;

        var transactionId = "001";
        var id = "122";            
        var user = Help.SetId<User>(User.Register(id, new DateTime(2015, 01, 01, 00, 00, 01)), userId);

        _usersDb.Add(user);
        var userBonusBalanceRepository = _testContext.MoqUnitOfWork.MockUnitOfWork.Object.GetUserBonusAccountRepository();

        UserBonusAccount uba = userBonusBalanceRepository.GetForUser(user);
        uba.PayTo(
            new Domain.Core.Money { TotalAmount = 10, BonusAmount = 0 },
            new Domain.Core.Outlet
            {
                BonusPercentage = 50,
                IsLoyalty = true,
                Id = id,
                OutletId = "111"
            },
            transactionId,
            DateTime.Now);
        userBonusBalanceRepository.Update(uba);          

        //Act
        _testContext.UserApplicationService.SignOut(id);

        //Assert
        var firstOrDefault = this._balances.FirstOrDefault(x => x.UserId == user.Id && x.MerchantId == merchantId);
        Assert.IsTrue(firstOrDefault != null && firstOrDefault.Balance == 0);
        Assert.IsNotNull(this._transactions.Where(x => x.Id == transactionId && x.Type == BonusTransactionType.EraseFunds));
    }

域单元测试

    [TestMethod]
    public void UserBonusAccount_ClearBalances_shouldClearBalancesForAllMerchants()
    {
        long userId = 1;
        long firstMerchantId = 1;
        long secondMerchantId = 2;
        User user = User.Register("111", new DateTime(2015, 01, 01, 00, 00, 01));
        Shared.Help.SetId(user, userId);
        List<BonusTransaction> transactions = new List<BonusTransaction>();
        List<BonusBalance> balances = new List<BonusBalance>();

        var userBonusAccount = UserBonusAccount.Load(transactions.AsQueryable(), balances.AsQueryable(), user);

        userBonusAccount.PayTo(new Money {TotalAmount = 100, BonusAmount = 0},
            new Outlet
            {
                BonusPercentage = 10,
                IsLoyalty = true,
                MerchantId = firstMerchantId,
                OutletId = "4512345678"
            }, "001", DateTime.Now);

        userBonusAccount.PayTo(new Money {TotalAmount = 200, BonusAmount = 0},
            new Outlet
            {
                BonusPercentage = 10,
                IsLoyalty = true,
                MerchantId = secondMerchantId,
                OutletId = "4512345679"
            }, "002", DateTime.Now);

        userBonusAccount.ClearBalances();

        Assert.IsTrue(userBonusAccount.GetBalanceAt(firstMerchantId) == 0);
        Assert.IsTrue(userBonusAccount.GetBalanceAt(secondMerchantId) == 0);
    }

如您所见,这两个测试都检查用户余额是否为0,这是域责任。因此,问题是:应用程序层单元测试应该看起来如何,应该测试什么?我读过某个地方,单元测试应该在“用于流控制的应用程序服务和用于业务规则的域模型”中进行测试。有人可以详细说明并举例说明应测试什么样的应用程序层单元测试吗?

Dmi

应用服务单元测试

应用程序服务的职责包括输入验证,安全性和事务控制。所以这是您应该测试的!

以下是应用服务单元测试应提供的一些示例问题,并回答:

我的应用服务吗?

  • 传递垃圾时行为正确(例如,返回预期的错误)?
  • 只允许管理员访问它?
  • 在成功案例中正确提交交易?

根据您实现这些方面的精确程度,测试它们可能有意义,也可能没有意义。例如,安全性通常是以声明性的方式实现的(例如,具有C#属性)。在这种情况下,您可能会发现一种代码检查方法比使用单元测试检查每个应用程序服务的安全属性更合适。但是YMMV。

另外,请确保您的单元测试是实际的单元测试,即对所有内容(特别是域对象)进行存根或模拟。在测试中尚不清楚是这种情况(请参阅下面的旁注)。

一般应用服务的测试策略

对应用程序服务进行单元测试是一件好事。但是,在应用程序服务级别上,从长远来看,我发现集成测试更有价值。因此,我通常建议以下组合策略来测试应用程序服务:

  1. 为好的情况和坏的情况创建单元测试(如果需要,可以使用TDD样式)。输入验证很重要,因此请不要跳过不良情况。
  2. 为好的情况创建一个集成测试。
  3. 如果需要,请创建其他集成测试。

边注

您的单元测试包含一些代码气味。

例如,我总是直接在单元测试中实例化SUT(被测系统)。这样,您便确切知道它具有哪些依赖项,并且对其中的哪些项进行了存根,模拟或使用了真正的依赖项。在您的测试中,这一点还不清楚。

另外,您似乎依赖于字段来收集测试输出(this._balances例如)。如果测试类仅包含一个测试,通常这不是问题,但否则可能会出现问题。通过依赖字段,您可以依赖测试方法“外部”的状态。这会使测试方法难以理解,因为您不能只阅读测试方法,而是需要考虑整个类。与过度使用设置和拆卸方法时发生的问题相同。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

单元测试Spring Boot应用程序服务层

来自分类Dev

如何编写Primefaces / JSF应用程序的单元测试

来自分类Dev

如何对旧的遗留应用程序进行单元测试

来自分类Dev

如何在基于Click的CLI应用程序的单元测试中模拟组件?

来自分类Dev

如何在Python 3中对CherryPy Web应用程序进行单元测试?

来自分类Dev

如何在测试中为requirejs注入模块以对应用程序进行单元测试?

来自分类Dev

Android单元测试-startActivity()使应用程序/测试崩溃

来自分类Dev

在Apache Camel应用程序中,单元测试如何将模拟端点注入真实端点?

来自分类Dev

DDD-如何在应用程序层中重用代码?

来自分类Dev

React / Redux应用程序的单元测试

来自分类Dev

单元测试Spring Boot应用程序端点

来自分类Dev

Windows Phone 8单元测试应用程序FileNotFoundException

来自分类Dev

单元测试应用程序与硬件的接口-是否模拟

来自分类Dev

usql应用程序和脚本的单元测试

来自分类Dev

Windows Phone 8单元测试应用程序FileNotFoundException

来自分类Dev

Xcodebuild以不同的语言运行应用程序单元测试

来自分类Dev

在单元测试SQLAlchemy应用程序中使用Alembic?

来自分类Dev

哪个单元测试框架用于 JavaFX 应用程序?

来自分类Dev

如何让单元测试快速访问应用程序的目标类

来自分类Dev

如何对部署在Tomcat上的Jersey Web应用程序进行单元测试?

来自分类Dev

如何使用库,单元测试和iOS应用程序组织XCode项目结构?

来自分类Dev

当需要WPF应用程序时如何进行单元测试?

来自分类Dev

如何运行单元测试项目并将结果返回到外部应用程序?

来自分类Dev

如何编写Python龙卷风应用程序的单元测试?

来自分类Dev

如何使用Twisted Trial在高速公路应用程序上进行单元测试?

来自分类Dev

如何使用AngularJS,Jasmine和Karma设置Cordova应用程序的单元测试

来自分类Dev

如何在Xcode 6上对应用程序扩展进行单元测试

来自分类Dev

如何对aiohttp.web应用程序进行单元测试

来自分类Dev

如何使用robolectric单元测试android录音应用程序

Related 相关文章

  1. 1

    单元测试Spring Boot应用程序服务层

  2. 2

    如何编写Primefaces / JSF应用程序的单元测试

  3. 3

    如何对旧的遗留应用程序进行单元测试

  4. 4

    如何在基于Click的CLI应用程序的单元测试中模拟组件?

  5. 5

    如何在Python 3中对CherryPy Web应用程序进行单元测试?

  6. 6

    如何在测试中为requirejs注入模块以对应用程序进行单元测试?

  7. 7

    Android单元测试-startActivity()使应用程序/测试崩溃

  8. 8

    在Apache Camel应用程序中,单元测试如何将模拟端点注入真实端点?

  9. 9

    DDD-如何在应用程序层中重用代码?

  10. 10

    React / Redux应用程序的单元测试

  11. 11

    单元测试Spring Boot应用程序端点

  12. 12

    Windows Phone 8单元测试应用程序FileNotFoundException

  13. 13

    单元测试应用程序与硬件的接口-是否模拟

  14. 14

    usql应用程序和脚本的单元测试

  15. 15

    Windows Phone 8单元测试应用程序FileNotFoundException

  16. 16

    Xcodebuild以不同的语言运行应用程序单元测试

  17. 17

    在单元测试SQLAlchemy应用程序中使用Alembic?

  18. 18

    哪个单元测试框架用于 JavaFX 应用程序?

  19. 19

    如何让单元测试快速访问应用程序的目标类

  20. 20

    如何对部署在Tomcat上的Jersey Web应用程序进行单元测试?

  21. 21

    如何使用库,单元测试和iOS应用程序组织XCode项目结构?

  22. 22

    当需要WPF应用程序时如何进行单元测试?

  23. 23

    如何运行单元测试项目并将结果返回到外部应用程序?

  24. 24

    如何编写Python龙卷风应用程序的单元测试?

  25. 25

    如何使用Twisted Trial在高速公路应用程序上进行单元测试?

  26. 26

    如何使用AngularJS,Jasmine和Karma设置Cordova应用程序的单元测试

  27. 27

    如何在Xcode 6上对应用程序扩展进行单元测试

  28. 28

    如何对aiohttp.web应用程序进行单元测试

  29. 29

    如何使用robolectric单元测试android录音应用程序

热门标签

归档