我是否需要为服务类中只调用存储库类中的方法的方法编写单元测试?

时间:2009-07-06 18:38:58

标签: unit-testing mocking

示例

我有一个存储库类(DAL):

public class MyRepository : IMyRepository
{
    public void Delete(int itemId)
    {
        // creates a concrete EF context class
        // deletes the object by calling context.DeleteObject()
    }

    // other methods
}

我还有一个服务类(BLL):

public class MyService
{
    private IMyRepository localRepository;

    public MyService(IMyRepository instance)
    {
        this.localRepository = instance;
    }

    public void Delete(int itemId)
    {
        instance.Delete(itemId);
    }

    // other methods
}

为MyRepository创建单元测试比实现它需要更多的时间,因为我必须模拟实体框架上下文。

但是为MyService创建单元测试似乎是无稽之谈,因为它只调用Repository。我可以检查的是验证它是否确实调用了存储库删除方法。

问题

您如何建议对这些Delete方法进行单元测试。都?一?没有?你会测试什么?

5 个答案:

答案 0 :(得分:1)

是的,两者都是。

IMyRepository mock = ...;
// create Delete(int) expectation

MyService service = new MyService(mock);
service.Delete(100);

// Verify expectations

您现在的Delete方法可能只调用存储库中的Delete方法,但这并不意味着它总是会。您希望对此进行单元测试,以部分验证其行为是否正确,部分是为了定义存储库工作方式的规范。

如果存储库为null,您还应该有一个测试来验证构造函数是否会抛出异常。您可能还需要在此方法中执行其他验证,例如非负ID或非零ID。也许这不会发生在这里,通过创建验证预期行为的测试使其成为规范的一部分。

它们似乎微不足道,但我可以保证它有一天会改变,你的期望和规格可能无法验证。

答案 1 :(得分:1)

是的,我肯定会为服务层编写单元测试。这样做的原因是,您不仅要测试您的实现现在是否正常工作,而且您还测试它将来会继续运行。

这是一个需要理解的重要概念。如果有人稍后出现并更改了ServiceLayer,并且没有单元测试,那么如何验证该功能是否继续有效?

我也会为你的DAL编写测试,但我会将它们放在一个名为DataTests的独立程序集中。这里的目的是隔离您对组件的关注。单元测试真的不应该关注你的DAL。

答案 2 :(得分:0)

为服务创建测试。 目前它所做的只是调用Repository Delete方法;但是,你不应该在意这一点。如果以后发生了什么事情并且功能变得复杂得多怎么办?您是否希望拥有可确保功能仍按预期工作的单元测试代码?

如果您通过自己的服务公开了“删除”,那么您希望它会产生效果。编写单元测试来测试该效果。根据您的特定需求,我会说您可能不需要对Repository Delete进行测试,特别是如果该功能是作为Service Delete功能的一部分进行的,但实际上这取决于您的覆盖范围。重新尝试。

答案 3 :(得分:0)

另外,如果您使用TDD创建了此代码,那么您将进行测试。实际上,人们是否可以通过您的服务呼叫删除,因此您实际上必须对其进行测试。

答案 4 :(得分:0)

在我看来,你需要测试两者。也许你可以在一个单独的工厂中创建EF上下文类,可以更容易地测试并模拟MyRepository测试的上下文类。这将更容易,并且使用工厂创建上下文调用对我来说似乎很安静。