添加到使用 TDD 进行单元测试的私有列表
Adding to private list for unit tests with TDD
我正在学习 TDD 和模拟,我想知道如何将一些对象添加到私有列表以测试方法和 属性。我的代码的基本部分如下:
public class Account
{
private List<Transaction> transactions = new List<Transaction>();
public decimal Balance
{
get
{
throw new NotImplementedException();
// Should be calculated by adding amounts of all transactions
// from private list
}
}
public void AddTransaction(Transaction transaction)
{
throw new NotImplementedException();
}
}
public class Transaction
{
public decimal Amount { get; set; }
public string Note { get; set; }
public DateTime DateTime { get; set; }
public Transaction(decimal amount, string note, DateTime dateTime)
{
Amount = amount;
Note = note;
DateTime = dateTime;
}
}
我想测试 属性 余额,但我不知道如何向列表中添加一些数据。我可以使用 Mock 来做到这一点,还是应该先为 AddTransaction 编写代码,然后在余额测试中使用它?
我可以想到三种可能的选项来测试这种代码。
- 如您所述,实施 AddTransaction 代码并在您的测试中使用它来比较 Balance 的值。
- 您可以潜在地进行交易 属性 public 并在您的测试中模拟它。
- 修改账户 class 通过添加一个构造函数,允许您使用交易参数初始化账户,然后您可以模拟交易并将其注入测试中的 class。
您应该仅使用暴露给消费者的 public "endpoints" 来测试您的 class。
在您的情况下,它将是 constructor
、AddTransaction
和 Balance
。
您的 class 的职责是添加交易并计算余额。
因此,在您的测试中,您将添加交易并检查 Balance
returns 预期结果。 AddTransaction
方法将通过 Balance
属性.
的测试进行测试
如果您首先通过编写测试来接近解决方案,那么您无需关心是否有私有列表或字典或其他东西。
例如第一个测试看起来像
var transaction = new Transaction(12.4m, "note", 12.January(2018));
var account = new Account();
account.AddTransaction(transaction);
account.Balance.Should().Be(12.4m);
第二次测试
var transaction1 = new Transaction(50.00m, "note1", 12.January(2018));
var transaction2 = new Transaction(45.99m, "note2", 13.January(2018));
var transaction3 = new Transaction(4.01m, "note3", 14.January(2018));
var account = new Account();
account.AddTransaction(transaction1);
account.AddTransaction(transaction2);
account.AddTransaction(transaction3);
account.Balance.Should().Be(100.0m);
可以在哪里实施
private decimal _balance;
public void AddTransaction(Transaction transaction)
{
_balance += transaction.Amount;
}
public decimal Balance => _balance;
如你所见,class可以不用list实现。如果应用程序使用 Balance
的次数比 AddTransaction
方法多得多,则上述方法可能有效。
通过进行不知道实现的测试,您可以在不更改测试的情况下自由重构 class。
显然,您首先需要为 Balance 和 AddTransaction 方法实现 getter。现在,很容易测试 Balance。您在测试方法中创建一个或两个已知金额的交易,调用 AddTransactions 将它们添加到帐户中,然后获取 Balance 的值并将其与所有金额的总和进行比较。
要测试添加交易,您必须稍微修改您的帐户 class。我看到的选项是:
- 添加一个可以接受交易列表的构造函数(正如 Ethan 已经提到的)。
- 您可能对第一种方法有所顾虑,因为这种方法可以更好地控制帐户。如果是这样的话,您可以创建一个方法来获取帐户中的交易数量,并根据该方法测试 AddTransactions。
- 创建一个 GetFirstTransaction 和一个 GetLastTransaction 方法并基于它们测试您的 AddTransaction 方法。
- 这样做不值得,但可以创建一个 public 属性,只需要一个 getter,returns 交易列表的深层副本,你可以在你的测试方法中测试它。
我正在学习 TDD 和模拟,我想知道如何将一些对象添加到私有列表以测试方法和 属性。我的代码的基本部分如下:
public class Account
{
private List<Transaction> transactions = new List<Transaction>();
public decimal Balance
{
get
{
throw new NotImplementedException();
// Should be calculated by adding amounts of all transactions
// from private list
}
}
public void AddTransaction(Transaction transaction)
{
throw new NotImplementedException();
}
}
public class Transaction
{
public decimal Amount { get; set; }
public string Note { get; set; }
public DateTime DateTime { get; set; }
public Transaction(decimal amount, string note, DateTime dateTime)
{
Amount = amount;
Note = note;
DateTime = dateTime;
}
}
我想测试 属性 余额,但我不知道如何向列表中添加一些数据。我可以使用 Mock 来做到这一点,还是应该先为 AddTransaction 编写代码,然后在余额测试中使用它?
我可以想到三种可能的选项来测试这种代码。
- 如您所述,实施 AddTransaction 代码并在您的测试中使用它来比较 Balance 的值。
- 您可以潜在地进行交易 属性 public 并在您的测试中模拟它。
- 修改账户 class 通过添加一个构造函数,允许您使用交易参数初始化账户,然后您可以模拟交易并将其注入测试中的 class。
您应该仅使用暴露给消费者的 public "endpoints" 来测试您的 class。
在您的情况下,它将是 constructor
、AddTransaction
和 Balance
。
您的 class 的职责是添加交易并计算余额。
因此,在您的测试中,您将添加交易并检查 Balance
returns 预期结果。 AddTransaction
方法将通过 Balance
属性.
如果您首先通过编写测试来接近解决方案,那么您无需关心是否有私有列表或字典或其他东西。
例如第一个测试看起来像
var transaction = new Transaction(12.4m, "note", 12.January(2018));
var account = new Account();
account.AddTransaction(transaction);
account.Balance.Should().Be(12.4m);
第二次测试
var transaction1 = new Transaction(50.00m, "note1", 12.January(2018));
var transaction2 = new Transaction(45.99m, "note2", 13.January(2018));
var transaction3 = new Transaction(4.01m, "note3", 14.January(2018));
var account = new Account();
account.AddTransaction(transaction1);
account.AddTransaction(transaction2);
account.AddTransaction(transaction3);
account.Balance.Should().Be(100.0m);
可以在哪里实施
private decimal _balance;
public void AddTransaction(Transaction transaction)
{
_balance += transaction.Amount;
}
public decimal Balance => _balance;
如你所见,class可以不用list实现。如果应用程序使用 Balance
的次数比 AddTransaction
方法多得多,则上述方法可能有效。
通过进行不知道实现的测试,您可以在不更改测试的情况下自由重构 class。
显然,您首先需要为 Balance 和 AddTransaction 方法实现 getter。现在,很容易测试 Balance。您在测试方法中创建一个或两个已知金额的交易,调用 AddTransactions 将它们添加到帐户中,然后获取 Balance 的值并将其与所有金额的总和进行比较。 要测试添加交易,您必须稍微修改您的帐户 class。我看到的选项是:
- 添加一个可以接受交易列表的构造函数(正如 Ethan 已经提到的)。
- 您可能对第一种方法有所顾虑,因为这种方法可以更好地控制帐户。如果是这样的话,您可以创建一个方法来获取帐户中的交易数量,并根据该方法测试 AddTransactions。
- 创建一个 GetFirstTransaction 和一个 GetLastTransaction 方法并基于它们测试您的 AddTransaction 方法。
- 这样做不值得,但可以创建一个 public 属性,只需要一个 getter,returns 交易列表的深层副本,你可以在你的测试方法中测试它。