使用Autofac.Moq检查其他方法时,如何正确模拟方法以返回特定数据?

A.阿纳托利

拥有这样的C#代码,并尝试检查IsFailureProcessStatus方法以返回true。dapper类SqlMapper中的查询方法,该方法使用参数调用存储过程。

public class DatabaseManager : IDatabaseManager
{
        private readonly SqlConnection CoreDbProcessesConnection;
        private readonly SqlConnection HrReportDbConnection;
        // there are other private fields with parameters and sql-procedures names

        public DatabaseManager(IDbConnectionsProvider dbConnectionsProvider)
        {
            this.CoreDbProcessesConnection = dbConnectionsProvider.CoreDbProcessesConnection;
            this.HrReportDbConnection = dbConnectionsProvider.HrReportDbConnection;
        }

        public List<CoreProcessStatusDto> GetProcessStatusIds(string ProcessName, DateTime dateTime)
        {
            var parameters = new DynamicParameters();
            parameters.Add(processStatusProcedureParamName01, ProcessName);
            parameters.Add(processStatusProcedureParamName02, dateTime);

            var output = this.CoreDbProcessesConnection
                .Query<CoreProcessStatusDto>(ProcessStatusProcedureName, parameters, commandType: CommandType.StoredProcedure).ToList();

            return output;
        }

        public bool IsFailureProcessStatus(StepDto.StepDescription step, DateTime dateTime)
        {
            bool isStepFailure = true;

            Stopwatch doStepUntil = new Stopwatch();
            doStepUntil.Start();

            while (doStepUntil.Elapsed < TimeSpan.FromSeconds(step.SecondsElapsed))
            {

                step.StatusTypesList = this.GetProcessStatusIds(step.ProcessName, dateTime);
                var statusTypesStepSelection = step.StatusTypesList.Select(st => st.ProcessStatusTypeId).ToList();

                //...
                // if...else operations here to make step true or false
                //...
            }

            doStepUntil.Stop();

            return isStepFailure;
       }
}

单元测试代码位于以下位置:

    [TestClass]
    public class DatabaseManagerTests
    {
       [TestMethod]
        public void IsFailureProcessStatus_ReturnTrue()
        {
            DateTime dateTime = DateTime.Now;

            StepDto step1Dto = new StepDto()
            {
                JobName = "ETL - HR - FilesImport - Reporting",
                JobStepName = "RunMCP_User_Department_Map",
                Step = new StepDto.StepDescription()
                {
                    StatusTypesList = new List<CoreProcessStatusDto>(),
                    ProcessName = "HR_User_Department_Map_Import",
                    SecondsElapsed = 30,
                    PackageCount = 2
                }
            };

            using (var mock = AutoMock.GetLoose())
            {
                var dbProviderMock = new Mock<IDbConnectionsProvider>(MockBehavior.Loose);

                var dbMock = new Mock<DatabaseManager>(dbProviderMock.Object);

                mock.Mock<IDatabaseManager>()
                    .Setup(p => p.GetProcessStatusIds(step1Dto.Step.ProcessName, dateTime))
                    .Returns(GetCoreProcessesStatusIdsTest());

                var sut = mock.Provide(dbMock.Object);

                //var sut = mock.Create<DatabaseManager>();

                var actual = sut.IsFailureProcessStatus(step1Dto.Step, dateTime);

                Assert.IsTrue(actual);
            }
        }

        private List<CoreProcessStatusDto> GetCoreProcessesStatusIdsTest()
        {
            var output = new List<CoreProcessStatusDto>()
            {
                new CoreProcessStatusDto() { ProcessStatusTypeId = 3 },
                new CoreProcessStatusDto() { ProcessStatusTypeId = 2 }
            };

            return output;
        }
    }

我尝试将GetProcessStatusIds方法设置为在调用sut.IsFailureProcessStatus代码时返回值,但是在调试其运行GetProcessStatusIds并尝试调用Query方法时抛出NullReferenceException异常。

Test Name:  IsFailureProcessStatus_ReturnTrue
Test Outcome:   Failed
Result StackTrace:  
at Dapper.SqlMapper.<QueryImpl>d__140`1.MoveNext() in C:\projects\dapper\Dapper\SqlMapper.cs:line 1066
   at System.Collections.Generic.List`1..ctor(IEnumerable`1 collection)
   at System.Linq.Enumerable.ToList[TSource](IEnumerable`1 source)
   at Dapper.SqlMapper.Query[T](IDbConnection cnn, String sql, Object param, IDbTransaction transaction, Boolean buffered, Nullable`1 commandTimeout, Nullable`1 commandType) in C:\projects\dapper\Dapper\SqlMapper.cs:line 721
   at ATP.HR.FolderWatcher.Service.Managers.DatabaseManager.GetProcessStatusIds(String ProcessName, DateTime dateTime) in C:\HOME\anatolii.dmitryv\src\HRM\hr-folder-watcher-service\ATP.HR.FolderWatcher.Service\Managers\DatabaseManager.cs:line 46
   at ATP.HR.FolderWatcher.Service.Managers.DatabaseManager.IsFailureProcessStatus(StepDescription step, DateTime dateTime) in C:\HOME\anatolii.dmitryv\src\HRM\hr-folder-watcher-service\ATP.HR.FolderWatcher.Service\Managers\DatabaseManager.cs:line 83
   at ATP.HR.FolderWatcher.Service.Test.DatabaseManagerTests.IsFailureProcessStatus_ReturnTrue() in C:\HOME\anatolii.dmitryv\src\HRM\hr-folder-watcher-service\ATP.HR.FolderWatcher.Service.Tests\DatabaseManagerTests.cs:line 57
Result Message: 
Test method ATP.HR.FolderWatcher.Service.Test.DatabaseManagerTests.IsFailureProcessStatus_ReturnTrue threw exception: 
System.NullReferenceException: Object reference not set to an instance of an object.

在模拟这种方法时,我到底做错了什么?我怎么说可以测试不要运行此GetProcessStatusIds并仅返回硬编码值?

尝试使用此方法,但对我不起作用:

using (var mock = AutoMock.GetLoose())
{

      mock.Mock<IDatabaseManager>()
          .Setup(p => p.GetProcessStatusIds(It.IsAny<string>(), It.IsAny<DateTime>()))
          .Returns(GetCoreProcessesStatusIdsTest());

          var sut = mock.Create<DatabaseManager>();

          var actual = sut.IsFailureProcessStatus(step1Dto.Step, dateTime);

          Assert.IsTrue(actual);
}
沙哈尔·肖克拉尼(Shahar Shokrani)

进行单元测试时的第一件事是定义测试的目标,在您要测试的内部逻辑IsFailureProcessStatus的问题中,这里的问题是您模拟IDatabaseManager具有该IsFailureProcessStatus方法的接口

您不需要那种模拟IDatabaseManager只有当它用作其他客户服务的提供者时,才需要模拟

并且因为您正在测试内部逻辑,所以IsFailureProcessStatus您只需模拟和执行内部逻辑执行所需的设置方法,IDbConnectionsProvider然后设置其方法即可CoreDbProcessesConnection用于DatabaseManager实际实例。

var dbProviderMock = new Mock<IDbConnectionsProvider>(MockBehavior.Loose);

dbProviderMock
    .Setup(p => p.CoreDbProcessesConnection)
    .Returns(new SqlConnection(...));

DatabaseManager databaseManager = new DatabaseManager(dbProviderMock.Object);

var actual = databaseManager.IsFailureProcessStatus(step1Dto.Step, dateTime);

Assert.IsTrue(actual);

我能理解您为什么错误地尝试了模拟GetProcessStatusIds,但是由于我们拥有的真实实例DatabaseManager,所以不需要使用它,因此您将仅模拟在执行过程中所需的依赖接口GetProcessStatusIds,这就是为什么我们在这里不需要设置的原因的HrReportDbConnection

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

如何使用Autofac注入AutoMapper?

来自分类Dev

使用Autofac进行属性注入的正确方法

来自分类Dev

如何使用Autofac的方法关联事件?

来自分类Dev

如何使用Autofac的方法关联事件?

来自分类Dev

如何使用其他方法的输入?

来自分类Dev

如何使用Autofac正确配置InstancePerTenant?

来自分类Dev

如何使用 Autokey 或其他方法模拟 Alt F4

来自分类Dev

使用Autofac.Extras.NHibernate时出错

来自分类Dev

如何使用Autofac容器解析类型的实例?

来自分类Dev

如何使用Autofac解决Action参数

来自分类Dev

如何使用autofac注册键入的httpClient服务?

来自分类Dev

Autofac如何使用多个名称注册服务?

来自分类Dev

如何使用Autofac为DbContext注册参数?

来自分类Dev

如何使用Autofac简化组件注册

来自分类Dev

如何使用PowerShell或其他方法检查是否写入了网络位置上的文件?

来自分类Dev

如何使用继承或其他方法正确地编写我的POJO?

来自分类Dev

使用autofac创建需要参数的对象的正确方法是什么?

来自分类Dev

使用autofac创建需要参数的对象的正确方法是什么?

来自分类Dev

使用os.walk()时如何排除目录?其他方法无效

来自分类Dev

当用户使用其他方法登录时如何关闭 One-Tap 提示?

来自分类Dev

如何使用其他方法在Angular材质底表与其父级之间共享数据

来自分类Dev

如何在其他方法中使用来自 observable 的数据?

来自分类Dev

如何使用yum或其他方法删除docker

来自分类Dev

如何使用Autofac使用工厂解析界面

来自分类Dev

如何使用context.forward与autofac一起使用

来自分类Dev

如何使用Autofac在构造函数中注入特定的实现

来自分类Dev

与 Autofac 集成时,如何使用 JWT 识别租户?

来自分类Dev

与Moq一起使用AutoFac属性注入

来自分类Dev

使用Moq和Autofac进行单元测试

Related 相关文章

  1. 1

    如何使用Autofac注入AutoMapper?

  2. 2

    使用Autofac进行属性注入的正确方法

  3. 3

    如何使用Autofac的方法关联事件?

  4. 4

    如何使用Autofac的方法关联事件?

  5. 5

    如何使用其他方法的输入?

  6. 6

    如何使用Autofac正确配置InstancePerTenant?

  7. 7

    如何使用 Autokey 或其他方法模拟 Alt F4

  8. 8

    使用Autofac.Extras.NHibernate时出错

  9. 9

    如何使用Autofac容器解析类型的实例?

  10. 10

    如何使用Autofac解决Action参数

  11. 11

    如何使用autofac注册键入的httpClient服务?

  12. 12

    Autofac如何使用多个名称注册服务?

  13. 13

    如何使用Autofac为DbContext注册参数?

  14. 14

    如何使用Autofac简化组件注册

  15. 15

    如何使用PowerShell或其他方法检查是否写入了网络位置上的文件?

  16. 16

    如何使用继承或其他方法正确地编写我的POJO?

  17. 17

    使用autofac创建需要参数的对象的正确方法是什么?

  18. 18

    使用autofac创建需要参数的对象的正确方法是什么?

  19. 19

    使用os.walk()时如何排除目录?其他方法无效

  20. 20

    当用户使用其他方法登录时如何关闭 One-Tap 提示?

  21. 21

    如何使用其他方法在Angular材质底表与其父级之间共享数据

  22. 22

    如何在其他方法中使用来自 observable 的数据?

  23. 23

    如何使用yum或其他方法删除docker

  24. 24

    如何使用Autofac使用工厂解析界面

  25. 25

    如何使用context.forward与autofac一起使用

  26. 26

    如何使用Autofac在构造函数中注入特定的实现

  27. 27

    与 Autofac 集成时,如何使用 JWT 识别租户?

  28. 28

    与Moq一起使用AutoFac属性注入

  29. 29

    使用Moq和Autofac进行单元测试

热门标签

归档