Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/298.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何模拟实体管理器_C#_Unit Testing - Fatal编程技术网

C# 如何模拟实体管理器

C# 如何模拟实体管理器,c#,unit-testing,C#,Unit Testing,我是单元测试新手,刚刚开始为现有代码库编写单元测试 我想为类的以下方法编写一个单元测试 public int ProcessFileRowQueue() { var fileRowsToProcess = this.EdiEntityManager.GetFileRowEntitiesToProcess(); foreach (var fileRowEntity in fileRowsToProcess) { Proc

我是单元测试新手,刚刚开始为现有代码库编写单元测试

我想为类的以下方法编写一个单元测试

public int ProcessFileRowQueue()
    {
        var fileRowsToProcess = this.EdiEntityManager.GetFileRowEntitiesToProcess();
        foreach (var fileRowEntity in fileRowsToProcess)
        {
           ProcessFileRow(fileRowEntity);
        }
        return fileRowsToProcess.Count;
    }
问题出在
getFileRowentiesToProcess()上实体管理器是实体框架上下文的包装器。我对此进行了搜索,发现一个解决方案是使用一个已知状态的测试数据库进行测试。然而,在我看来,在测试代码中创建一些实体将产生更一致的测试结果

但由于它的存在,我看不到一种不进行重构就模仿管理器的方法


是否有解决此问题的最佳实践?我很抱歉这个问题有点幼稚,但我只是想确保我在项目的其余部分走的是正确的道路。

我在这里听到两个问题:

我应该模仿eDiscoveryManager吗?

对。它是测试代码外部的依赖项,其创建和行为在代码外部定义。因此,出于测试目的,应该注入具有已知行为的模拟

如何模拟eDiscoveryManager?

我们无法从公布的代码中得知。这取决于该类型是什么,它是如何创建和提供给该包含对象的,等等。要回答这部分问题,您应该尝试:

  • 为正在调用的一个方法创建具有已知行为的模拟(
    getFileRowentiestoProcess()
  • 将该模拟注入正在测试的包含对象
  • 对于这两种努力中的任何一种,都要找出可能阻止这种情况发生的原因。每一个这样的发现要么将涉及对类型和模拟的更多了解,要么将揭示重构的需要,以允许可测试性。发布的代码没有透露这一点

    例如,假设在构造函数中创建了
    EdiEntityManager

    public SomeObject()
    {
        this.EdiEntityManager = new EntityManager();
    }
    
    这将是防止嘲笑的东西,因为它会妨碍上面的步骤2。相反,构造函数将被重构为需要而不是实例化:

    public SomeObject(EntityManager ediEntityManager)
    {
        this.EdiEntityManager = ediEntityManager;
    }
    
    这将允许测试提供模拟,并符合依赖项反转原则


    或者可能
    EntityManager
    是一个太具体的类型,很难模拟/注入,那么可能实际的类型应该是
    EntityManager
    定义的接口。这个问题最糟糕的情况可能是您根本不控制类型,只需要定义一个包装器对象(它本身有一个可模拟的接口)来封装
    EntityManager
    依赖项。

    这里的依赖项看起来像
    his
    。是否可以对其进行模拟,并反过来为
    EdiEntityManager
    返回一个已知(也是模拟的)对象,该对象本身具有
    getFileRowentiestoProcess()的已知行为存根?因为
    his
    在测试的代码之外,所以它是依赖项,应该是模拟项。无论这段代码在哪里,他的
    都应该是模拟代码被注入的地方。对不起,这是一个输入错误。本应是“这一点”,但同样的原则仍然适用。什么是
    EdiEntityManager
    ?它能被嘲笑吗?这是外部依赖,应该加以嘲弄。无论它填充到对象中的什么地方,都会注入模拟。我想我的意思是,到底是什么阻止你去模仿它呢?因为它有300行代码,32个方法,而且似乎需要模仿很多工作,但也许我缺少一些关于如何模仿它的东西。我建议从模仿框架开始(我个人喜欢Rhinomock,但任何都可以)尝试为该类型创建一个模拟,并将模拟注入到对象中。对于这两种情况中的任何一种(创建、注入),确定可能存在的阻碍因素。(如果类不可模仿,那么您可能需要将其包装在可模仿的接口中,如果包含的对象不可注射,那么您可能需要使其可注射。)“我是否应该模仿它”的问题是一个简单的“是”,但can you完全是另一个问题,提供的信息无法回答这个问题。