gpt4 book ai didi

c# - 使用服务进行验证时如何对 IValidatableObject Validate 进行单元测试?

转载 作者:行者123 更新时间:2023-12-03 23:41:33 26 4
gpt4 key购买 nike

我的 Validate方法是访问各种服务进行验证。这些服务是依赖注入(inject)的,可以使用 validationContext.GetService 访问。方法。在运行时,这工作正常。

public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
{
var logic = (ShipRegistrationLogic)validationContext.GetService(typeof(ShipRegistrationLogic));
var userManager = (UserManager<IdentityUser>)validationContext.GetService(typeof(UserManager<IdentityUser>));
var spaceTransitAuthority = (SpaceTransitAuthority)validationContext.GetService(typeof(ISpaceTransitAuthority));
var hull = logic.GetHull(HullId);
var user = userManager.FindByIdAsync(UserId).Result;

if (spaceTransitAuthority.CheckActualHullCapacity(hull) > logic.GetMaxAuthorizedMass(user))
{
yield return new ValidationResult("You do not have the required pilot's license for this hull.", new[] { nameof(HullId) });
}
}
我想对这个复杂的验证进行单元测试。但是,在执行测试期间,我无法弄清楚如何访问测试评估所需的服务。如 GetService返回 null在试运行期间。
我正在使用 MoqxUnit ,并且我尝试过模拟 ValidationContext 的 GetService 方法但没有成功,因为 ValidationContext 是一个密封类,无法模拟。
这是显示我尝试过的测试:
[Theory]
[InlineData(1)]
[InlineData(2)]
[InlineData(3)]
public void Validate_ShouldPassMassCheck(int hullId)
{
// Arrange
var userId = _users[0].Id;
var viewModel = new ShipRegistrationViewModel()
{
UserId = userId,
HullId = hullId
};

var hull = new Hull()
{
DefaultMaximumTakeOffMass = TakeOffMassEnum.Tank,
Id = hullId,
Name = "Test"
};

var shipRegistrationLogicMock = new Mock<ShipRegistrationLogic>();
var spaceTransitAuthorityMock = new Mock<ISpaceTransitAuthority>();
shipRegistrationLogicMock.Setup(x => x.GetHull(hullId)).Returns(hull);
shipRegistrationLogicMock.Setup(x => x.GetMaxAuthorizedMass(_users[0])).Returns((int)TakeOffMassEnum.Tank);
_userManager.Setup(x => x.FindByNameAsync(userId))
.ReturnsAsync(new IdentityUser()
{
UserName = "user",
});

spaceTransitAuthorityMock.Setup(x => x.CheckActualHullCapacity(hull)).Returns((double)TakeOffMassEnum.Tank);

var context = new Mock<ValidationContext>(viewModel);
context.Setup(x => x.GetService(typeof(ShipRegistrationLogic))).Returns(shipRegistrationLogicMock);
context.Setup(x => x.GetService(typeof(UserManager<IdentityUser>))).Returns(_userManager);
context.Setup(x => x.GetService(typeof(ISpaceTransitAuthority))).Returns(spaceTransitAuthorityMock);

// Act
var results = viewModel.Validate(context.Object);

// Assert
Assert.Single(results);
Assert.Equal(ValidationResult.Success, results.First());
}

最佳答案

您可以模拟 IServiceProvider并将其传递给构造函数:

var services = new Mock<IServiceProvider>();
services.Setup(x => x.GetService(typeof(ShipRegistrationLogic)))
.Returns(shipRegistrationLogicMock.Object);
services.Setup(x => x.GetService(typeof(UserManager<IdentityUser>)))
.Returns(_userManager.Object);
services.Setup(x => x.GetService(typeof(ISpaceTransitAuthority)))
.Returns(spaceTransitAuthorityMock.Object);

var context = new ValidationContext(viewModel, services.Object, null);

// Act
var results = viewModel.Validate(context);
也可以直接建一个 IServiceProvider没有模拟

关于c# - 使用服务进行验证时如何对 IValidatableObject Validate 进行单元测试?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65421937/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com