非单元测试问题

本文关键字:问题 单元测试 | 更新日期: 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在一个尝试…