如果你的接口叫做IAccountService,而你的服务实现的却是IService,会出现代码中一些打字错误。如果你的类名为AccountObj,但构造函数却叫AccountInfo,也会出现同样的问题。
因此,我们可以假设你的服务应该实现IAccountService,并且你的类应该命名为AccountInfo。
在编写测试AccountInfo.RefreshAmount的单元测试时,你需要了解该函数的要求。你必须确切地知道这个函数应该完成什么任务。
从代码中可以看出RefreshAmount的要求如下:
无论实现IAccountService的对象和使用哪个Id来构造AccountInfo类的对象,调用RefreshAmount后,属性Amount的值应该与IAccountService.GetAccountAmount(Id)返回的值相同。
更正式地说:
对于任何Id
对于实现IAccountService的任何类
使用Id和IAccountService构造的对象,在调用RefreshAmount()方法后,Amount属性的值应该等于IAccountService.GetAccountAmount(Id)返回的值。
由于要求它能适用于所有的Id和所有的AccountServices,因此你不能使用所有的这些进行测试。在编写单元测试时,你将不得不思考可能发生的错误。
在你的例子中,似乎没有明显的错误,但是对于未来版本,你可以考虑到函数可能会使用不正确的Id调用服务、调用错误的服务、忘记将返回值保存在Amount属性中或者Amount属性没有返回正确的值。
你类的要求指定它应该适用于每个Id和每个IAcocuntService。因此,你可以自由地提供任何你想要测试的Id和AccountService来构造你的测试对象,这些Id和AccountService能够检测到未来可能发生的四个错误中的任何一个。
幸运的是,一个简单的AccountInfo类就足以满足需求。
class AccountService : IAccountService
{
public double GetAccountAmount(int accountId)
{
return 137 * accountId - 472;
}
}
以下单元测试测试了提供的IAccountService实现返回的金额是否与多个Id对应的金额相同。
void TestAccountObj_RefreshAmount()
{
const int Id = 438;
IAccountService accountService = new AccountService();
var testObject = new AccountInfo(Id, accountService);
testObject.RefreshAmount();
double amount = testObject.Amount;
double expectedAmount = accountService.GetAccountAmount(Id);
Assert.AreEqual(expectedAmount, amount);
这个测试将会检测所有可能的四种错误。唯一无法发现的错误是,如果调用了错误的服务并且该服务返回与奇怪的计算数值完全相同的结果,则该测试不会发现此错误。这就是我在服务中放置如此奇怪的计算的原因,任何错误的调用服务返回相同错误的概率非常小。尤其是如果您使用不同的TestObject和不同的Ids进行测试。
AccountObj
如何使用该界面。 - René VogtAccountObj
看起来像一个实体。你不应该将依赖项注入到实体的构造函数中。 - Steven