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

如何解决使用服务进行验证时如何对 IValidatableObject Validate 进行单元测试?

我的 Validate 方法正在访问各种服务进行验证。这些服务是依赖注入的,可以使用 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

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?
Java在半透明框架/面板/组件上重新绘画。
Java“ Class.forName()”和“ Class.forName()。newInstance()”之间有什么区别?
在此环境中不提供编译器。也许是在JRE而不是JDK上运行?
Java用相同的方法在一个类中实现两个接口。哪种接口方法被覆盖?
Java 什么是Runtime.getRuntime()。totalMemory()和freeMemory()?
java.library.path中的java.lang.UnsatisfiedLinkError否*****。dll
JavaFX“位置是必需的。” 即使在同一包装中
Java 导入两个具有相同名称的类。怎么处理?
Java 是否应该在HttpServletResponse.getOutputStream()/。getWriter()上调用.close()?
Java RegEx元字符(。)和普通点?