代码之家  ›  专栏  ›  技术社区  ›  Robert Koritnik

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

  •  7
  • Robert Koritnik  · 技术社区  · 15 年前

    例子

    我有一个知识库类(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创建一个单元测试似乎是胡说八道,因为它只调用存储库。我能检查的只是验证它是否真的调用了存储库删除方法。

    问题

    您建议如何对这对删除方法进行单元测试。两者都有?一个?没有?你会测试什么?

    5 回复  |  直到 15 年前
        1
  •  1
  •   Joseph    15 年前

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

    这是一个需要理解的重要概念。如果稍后有人来更改您的服务层,并且没有单元测试,您如何验证功能是否继续工作?

    我也会为您的DAL编写测试,但我会将它们放在一个称为datatests或其他东西的单独程序集中。这里的目的是跨程序集隔离您的关注点。实际上,单元测试不应该与DAL有关。

        2
  •  1
  •   justin.m.chase    15 年前

    是的,都是。

    IMyRepository mock = ...;
    // create Delete(int) expectation
    
    MyService service = new MyService(mock);
    service.Delete(100);
    
    // Verify expectations
    

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

    您还可以进行一个测试来验证如果存储库为空,构造函数是否会抛出异常。在此方法中,您可能还需要进行其他验证,如非负ID或非零ID。可能不会在此处发生这种情况,请通过创建验证预期行为的测试将其作为规范的一部分。

    它们看起来微不足道,但我可以保证有一天它会改变,您的期望和规格可能不会得到验证。

        3
  •  0
  •   Paul Sonier    15 年前

    为服务创建测试。 目前 它所做的只是调用存储库删除方法;但是,您不应该关心这个问题。如果以后发生了什么事情,功能变得更加复杂,怎么办?您不想让单元测试代码确保功能仍按预期工作吗?

    如果您正在通过服务公开您的删除,那么您希望它具有效果。编写一个单元测试来测试这种效果。根据您的特定需求,我想说您可能不需要对存储库删除进行测试,特别是当该功能作为服务删除功能的一部分进行练习时,但这实际上取决于您所尝试的覆盖级别。

        4
  •  0
  •   John Saunders    15 年前

    另外,如果您使用TDD创建了这个代码,那么您将进行一个测试。实际上,人们是否可以通过您的服务调用Delete很重要,因此您实际上必须测试它。

        5
  •  0
  •   crauscher    15 年前

    在我看来,你需要检验两者。也许您可以在一个单独的工厂中创建ef上下文类,该工厂可以更容易地进行测试,并模拟用于myrepository测试的上下文类。这将更容易,使用工厂创建上下文调用对我来说似乎非常有用。