非单元测试问题
本文关键字:问题 单元测试 | 更新日期: 2023-09-27 18:17:31
好的,我有一个通过方法运行的Nunit测试类设置,让它全部CalcBalance()。在CalcBalance()中,我们有另一个方法可以将内容保存到数据库中。在测试此特定方法时,我不想处理数据库,但是当我运行测试时,数据库方法抛出异常并导致测试失败,因为数据库没有设置/模拟。例子:
CalcBalance()
{
//Stuff I want to test
DatabaseInteraction() //Throws exception
return; //This is the value I want to have tested.
}
我的问题是,是否有任何方法我可以设置这个,以便Nunit测试器将继续测试,即使数据库交互说它失败了。我注释掉了DatabaseInteraction()并运行测试,它通过的很好。
导致异常的DatabaseInteraction
内部功能应该抽象到实现接口的另一个类。这个接口可以在单元测试中模拟使用。
public class BalanceCalculator
{
readonly IDatabaseInteraction _databaseInteraction;
public BalanceCalculator(IDatabaseInteraction databaseInteraction)
{
_databaseInteraction = databaseInteraction;
}
public Decimal CalcBalance()
{
//Stuff I want to test
_databaseInteraction.Interaction();
return 5.0D; //This is the value I want to have tested.
}
}
然后在单元测试中,可以这样做(使用Moq):
[Test]
public void CheckValueTest()
{
Mock<IDatabaseInteraction> mockInteraction = Mock<IDatabaseInteraction>();
BalanceCalculator balanceCalculator = new BalanceCalculator(mockInteraction.Object);
decimal result = balanceCalculator.CalcBalance();
Assert.AreEqual(5.0D, result);
}
IDatabaseInteraction
被模拟为不做任何事情,因此不可能发生异常或任何不相关的功能。
要了解更多信息,请阅读控制反转,它对可测试性非常有用。
听起来像你需要拆分你的代码,这样每个函数/类都有自己的责任。分割后,您可以分别测试每个部分。
我不得不同意@Sebastiaan Megens的观点。"正确的"方法是
a)使用接口松散耦合数据库交互,然后在测试代码或 中简单地创建一个模拟数据库。b)设计你的代码,使每个对象都可以作为一个独立的实体。
也就是说,我相信你可以配置你的测试来预期一个特定类型的异常,这意味着如果在执行过程中抛出这样一个异常,它不会失败。虽然远非理想,但这是您为紧耦合架构付出的代价。在类似的思路,在你的测试简单包装的代码调用MyObject.CalcBalance
在一个尝试…