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

问题描述 投票:0回答:1

具有此类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);
}
c# unit-testing moq autofac dapper
1个回答
0
投票

问题是您正在将特定值传递给Setup方法。

It.IsAny<string>()方法中使用It.IsAny<DateTime>()Setup

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

如果仅需要接受特定值,则查看It.Is<T>,例如:

It.Is<string>(s => !string.IsNullOrEmpty(s))             // not empty
It.Is<string>(s => s.StartsWith("HR_"))                  // starts with
It.Is<string>(s => s == "HR_User_Department_Map_Import") // equals

浏览Moq Quickstart guide了解更多信息。>>

© www.soinside.com 2019 - 2024. All rights reserved.