我们正在为应用程序创建单元测试,但在创建某些测试时遇到了问题。
我们正在对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()函数返回。
我们要去哪里错了?