4

我正在使用与数据库交互的 api。这个 api 具有查询、加载和保存元素到数据库的方法。我已经编写了集成测试,它们执行诸如创建新实例之类的操作,然后检查当我对该实例进行查询时,是否找到了正确的实例。这一切都很好。

我想对此代码进行更快的单元测试,但我想知道任何单元测试的有用性以及它们是否真的给了我任何东西。例如,假设我有一个类可以通过 API 保存一些元素。这是伪代码,但了解我使用的 api 是如何工作的。

public class ElementSaver
{
    private ITheApi m_api;

    public bool SaveElement(IElement newElement, IElement linkedElement)
    {
        IntPtr elemPtr = m_api.CreateNewElement()
        if (elemPtr==IntPtr.Zero)
        {
            return false;
        }
        if (m_api.SetElementAttribute(elemPtr,newElement.AttributeName,newElement.AttributeValue)==false)
        {
             return false;
        }
        if (m_api.SaveElement(elemPtr)==false)
        {
             return false;
        }

        IntPtr linkedElemPtr = m_api.GetElementById(linkedElement.Id)
        if (linkedElemPtr==IntPtr.Zero)
        {
            return false; 
        }
        if (m_api.LinkElements(elemPtr,linkedElemPtr)==false)
        {
            return false;
        }
        return true;

    }
}  

是否值得编写模拟 m_api 成员的单元测试?似乎我可以测试,如果任何各种调用失败,则返回 false,如果所有各种调用都成功,则返回 true,并且我可以设置期望使用预期参数调用各种方法,但是这有用吗?如果我要重构这段代码,使它使用一些稍微不同的 api 方法,但获得相同的结果,这会破坏我的测试,我需要更改它们。这种脆性似乎不是很有用。

我应该为这样的代码进行单元测试,还是应该坚持使用已有的集成测试?

4

2 回答 2

4

看看测试是什么样的。如果您只测试传入的内容是否最终进入数据库等。您可能只做自动化集成测试就可以做正确的事情。如果有要测试的逻辑,那么您可能想看看是否可以将逻辑分解为单独的类,您可以对它们进行单元测试,并围绕不包含逻辑的基础设施代码进行外观。

于 2008-12-02T09:51:28.847 回答
2

出于以下原因,在我的代码中模拟 m_api 是个好主意(并非所有这些都适用于您的伪代码示例):

  • 正如您所提到的,您可以验证您的类是否正确执行错误处理
  • 如果您的类中有更复杂的代码(例如,缓存),您可以在您的模拟中使用期望来确保类的行为正确。例如,两次检索相同的对象,但确保 m_api 只被调用一次。
  • 您的单元测试可以在不创建适当数据集的情况下测试行为。随着 m_api 下的数据模型发生变化,这会随着时间的推移增加可维护性。
于 2008-12-02T09:48:04.390 回答