【问题标题】:Stuck at how to proceed unit testing this business logic using tdd坚持如何使用 tdd 对这个业务逻辑进行单元测试
【发布时间】:2013-07-27 18:56:34
【问题描述】:

我有一个方法,我给出停车场(Entries,Exits)中汽车运动(Operation 类)的列表,每个运动都有一个相关的汽车列表(OperationVehicle 类)。这种方法应该会产生我所说的汽车日志。它列出了所有汽车,在什么时间进入什么时间退出以及每辆汽车的持续时间。 我对首先要测试的东西有点迷茫。这个问题的答案对我来说就像一个教程。

如何继续使用 tdd 对这个特定逻辑进行单元测试?

public class Operation
    {
        public Operation()
        {
            OperationVehicles = new List<OperationVehicle>();
        }
        public int OperationId { get; set; }
        public DateTime Date { get; set; }
        public virtual OperationType OperationType { get; set; }
        public virtual List<OperationVehicle> OperationVehicles { get; set; }

    }

public class OperationVehicle
    {
        public int OperationVehicleId { get; set; }
        public OperationType OperationType { get; set; }
        public virtual Operation Operation { get; set; }
        public virtual Vehicle Vehicle { get; set; }
    }

public class CarLog
    {
        public int Id { get; set; }
        public DateTime Date { get; set; }
        public Vehicle Vehicle { get; set; }
        public int StayLength { get; set; }
    }

   public IEnumerable<CarLog> GenerateCarsLog(List<Operation> CarStayOperations)
        {
           // not implemented yet
            return new List<CarLog>();
        }

【问题讨论】:

  • 与任何其他方法相同。您使用参数调用该方法,并检查它返回的内容是否正确。具体问题是什么?您最佳尝试的代码在哪里?测试方法的代码在哪里?
  • 我并不拘泥于如何编写单元测试,而是要在这个特定的逻辑上测试什么案例。顺便说一句,我是单元测试的新手。我做了很多阅读。但我总是卡在现实世界的代码中。
  • 先测试名义情况。然后,如果有特殊情况(空列表,或无效参数,或其他),这些也是如此。使用您喜欢的代码覆盖率工具来检测您是否遗漏了某些情况。

标签: c# unit-testing tdd logic


【解决方案1】:

到目前为止,您已经用代码(关系)为您的域建模。但是你没有写太多逻辑,所以没有太多要测试的。

我不会让您的测试与这些类交互,至少一开始不会。相反,我可能会从用户界面的某个地方开始。模拟用户执行的操作(对于用户,我不一定指人类,但它可能是另一个系统)。测试行为,并在尽可能靠近系统边界的地方进行。

如果没有更多关于上下文的知识,很难回答究竟要编写什么测试。不过我会试一试的。

那么用户应该能够使用您的系统做什么呢?例如,编写一个汽车进入停车场的第一个测试,并让测试以某种方式断言汽车现在在停车场。

但是用户(或其他用户)如何知道汽车已成功进入停车场?例如,是否有某种用于 Car Log 的用户界面?让你的测试断言看看。

然而,这将是一个相当大的测试,包括输入汽车和检查汽车日志。最好从汽车日志开始:只是验证它是空的。或者也许您可以从更小的步骤开始?

我的回答有点试探性,因为它通常是这样的:你边学习边发现。

设计说明:请不要公开您的课程中的列表 (OperationVehicles)。它完全打破了封装。改为添加Operation.AddOperationVehicle() 方法并返回IEnumerable&lt;OperationVehicle&gt;

【讨论】:

  • +1 建议您应该从外向内工作。部分问题看起来像您的对象模型比需要的更复杂,这是您从以太中设计它的结果而不是由指定使用系统需要什么的测试来驱动。
  • @Torbjörn Kalin 感谢您的慷慨回答。我从哪里得到了一些想法。对于设计说明,此模型实际上是一个数据库模型,这是最有可能使用 ORM 之类的实体框架生成我的数据库的方式。
  • @tallseth 我认为你是对的,我的设计超载并且非常复杂,应该如此。我应该简化它。我认为这是主要原因。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-02-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多