从另一个类中模拟一个方法,该类从一个模拟方法中调用

时间:2019-11-18 11:19:20

标签: c# unit-testing .net-core moq

我们正在为应用程序创建单元测试,但在创建某些测试时遇到了问题。

我们正在对ActivateCommandHandler类的以下Handle()方法进行单元测试:

    public class ActivateCommand : IRequest<HttpResponseMessage>
    {
        public string Controller { get; set; }

        public ActivateCommand(string controllername)
        {
            this.Controller = controllername;
        }
    }

    public class ActivateCommandHandler : CommandHandler<ActivateCommand, HttpResponseMessage>
    {
        protected readonly ICommandsGateway _commandsGateway;
        protected readonly EndpointSettings _endpoints;
        protected readonly IUserProfile _userprofile;

        public ActivateCommandHandler(IMediator mediator, ICommandsGateway commandsGateway, IOptions<EndpointSettings> endpoints, IValidationContext validationContext, IUserProfile currentUser) : base(mediator, validationContext, currentUser)
        {
            _commandsGateway = commandsGateway;
            _endpoints = endpoints.Value;
            _userprofile = currentUser;
        }


        public override async Task<HttpResponseMessage> Handle(ActivateCommand command, CancellationToken cancellationToken)
        {
            if (_endpoints.EndpointExists(command.Controller))
            {
                // Check whether the second server controller is deactivated
                string peercontroller = _endpoints.GetPeerController(command.Controller);

                if (!string.IsNullOrEmpty(peercontroller))
                {
                    BaseRedundancySwitchStatus controllerStatus = await _commandsGateway.GetRedundancySwitchStatus(_endpoints.GetEndpointAddress(peercontroller));

                    if ((controllerStatus.CurrentState == "Activated") || (controllerStatus.CurrentState == "ActivatedWithWarning") || (controllerStatus.CurrentState == "Activating"))
                    {
                        var resp = new HttpResponseMessage(HttpStatusCode.Conflict)
                        {
                            Content = new StringContent($"{peercontroller},{controllerStatus.CurrentState}")
                        };

                        return resp;
                    }
                }

                var result = await _commandsGateway.PostActivateCommand(_endpoints.GetEndpointAddress(command.Controller));

                return result;
            }
            else
            {
                throw new InvalidControllerNameException($"ERROR: The controller {command.Controller} does not exist as an endpoint on this Control Center!");
            }
        }
    }

为此,对以下内容进行了模拟:_endpoints,command和_commandsGateway(接口)。这对于单元测试参数验证非常有用。但是,现在我们要测试将对等控制器状态设置为特定值时的行为。

为此,我们尝试模拟函数_commandsGateway.GetRedundancySwitchStatus()。以下是实际的测试实现。我们模拟_commandsGateway.GetRedundancySwitchStatus()函数以将预期的BaseRedundancySwitchStatus返回,并将CurrentState设置为“ Activated”。之后,我们调用要测试的实际函数的处理程序,并检查是否得到预期的错误。

[Fact]
        public async void ShouldHaveErrors_PeerControllerStateActivated()
        {
            var command = new ActivateCommand("Server Controller Slave1");

            BaseRedundancySwitchStatus result = new BaseRedundancySwitchStatus()
            {
                CurrentState = "Activated"
            };

            _commandsGateway
                .Setup(s => s.GetRedundancySwitchStatus("Server Controller Slave1"))
                .ReturnsAsync(result);

            HttpResponseMessage res = await _handler.Handle(command, CancellationToken.None);

            Assert.True(res.StatusCode == System.Net.HttpStatusCode.Conflict);
        }

在调试代码时,当我逐步遍历Handle()方法中调用_commandsGateway.GetRedundancySwitchStatus的代码时,我可以看到_endpoints.GetEndpointAddress(command.Controller)(这是参数)被调用并且正确的值返回。此后,调试器将跳至下一行,而无需任何指示已执行了模拟GetRedundancySwitchStatus()函数的指示。检查controllerStatus变量的值为空。我希望该值是BaseRedundancySwitchStatus对象,该对象应该由模拟的GetRedundancySwitchStatus()函数返回。

我们要去哪里错了?

0 个答案:

没有答案