0

好的,我有一个 Nunit 测试类设置,它通过一个方法运行,让它全部使用 CalcBalance()。在 CalcBalance() 中,我们有另一个方法可以将数据保存到数据库中。我不想在测试这个特定方法时处理数据库,但是当我运行我的测试时,数据库方法会抛出异常并导致测试失败,因为数据库没有设置/模拟。例子:

CalcBalance()
{

//Stuff I want to test

DatabaseInteraction()     //Throws exception

 return;         //This is the value I want to have tested.

}

我的问题是,有什么方法可以设置它,以便 Nunit 测试器将继续测试,即使数据库交互说它失败了。我注释掉了 DatabaseInteraction() 并运行了测试,结果很好。

4

3 回答 3

3

内部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.
    }
}

然后在单元测试中,可以这样做(使用起订量):

[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嘲笑为什么都不做,因此不可能发生异常或任何不相关的功能。

有关更多信息,请阅读Inversion of Control,它对可测试性非常有用。

于 2011-12-12T17:20:27.147 回答
0

在我看来,您需要拆分代码,以便每个函数/类都有自己的责任。拆分后,您可以分别测试每个部分。

于 2011-12-12T17:08:37.287 回答
0

我必须在这里同意@Sebastiaan Megens。实现这一目标的“正确”方法是

a)使用接口让您的数据库交互松散耦合,然后在测试代码中简单地创建一个模拟数据库或

b) 设计您的代码,使每个对象都可以作为独立实体运行。

话虽如此,我相信您可以将测试配置为预期某种类型的异常,这意味着如果在执行过程中抛出此类异常,它不会失败。远非理想,但这是您为紧耦合架构付出的代价。以类似的思路,在您的测试中,只需将调用MyObject.CalcBalancetry...catch 的代码包装起来,然后照常进行。

于 2011-12-12T17:18:55.353 回答