有“this”关键字时如何使用 xUnit 和 Moq 测试 web api 方法

如何解决有“this”关键字时如何使用 xUnit 和 Moq 测试 web api 方法

我正在尝试使用 xUnit 和 Moq 测试 web api 方法,但是出现了一种情况,因为它使用了“this”关键字。请查看代码

Web API 接口

public interface IRepository
{
    IEnumerable<Reservation> Reservations { get; }
    Reservation this[int id] { get; }
}

有这个关键字Reservation this[int id] { get; }

Web API 控制器

[ApiController]
[Route("api/[controller]")]
public class ReservationController : ControllerBase
{
    private IRepository repository;
    public ReservationController(IRepository repo) => repository = repo;

    [HttpGet]
    public IEnumerable<Reservation> Get() => repository.Reservations;

    [HttpGet("{id}")]
    public ActionResult<Reservation> Get(int id)
    {
        if (id == 0)
            return BadRequest("Value must be passed in the request body.");

        Reservation r = repository[id];

        if (r is null)
            return NotFound();

        return Ok(r);
    }
}

Web API 提供内存中的记录,而不是数据库中的记录。有一个包含硬编码记录的类 Repository.cs

public class Repository : IRepository
{
    private Dictionary<int,Reservation> items;

    public Repository()
    {
        items = new Dictionary<int,Reservation>();
        new List<Reservation> {
            new Reservation {Id=1,Name = "Jack",StartLocation = "Edinberg",EndLocation="Yeti" },new Reservation {Id=2,Name = "Nick",StartLocation = "Moscow",EndLocation="LKO" },new Reservation {Id=3,Name = "Ramon",StartLocation = "London",EndLocation="Paris" }
            }.ForEach(r => AddReservation(r));
    }

    public Reservation this[int id] => items.ContainsKey(id) ? items[id] : null;

    public IEnumerable<Reservation> Reservations => items.Values;

 }

现在我想模拟 web api 方法 Get(int id) 但不能因为 'this' 关键字。我尝试了下面的代码但失败了。

[Fact]
public void Test_GET_AReservations_BadRequest()
{
    // Arrange
    var mockRepo = new Mock<IRepository>();
    mockRepo.Setup(repo => repo.Reservations.this).Returns(Single());
    var controller = new ReservationController(mockRepo.Object);

    // Act
    var result = controller.Get();

    // Assert
    var model = Assert.IsAssignableFrom<IEnumerable<Reservation>>(result);
    Assert.Equal(3,model.Count());
}

private static Reservation Single()
{
    return new Reservation()
    {
        Id = 1,Name = "Test One",StartLocation = "SL1",EndLocation = "EL1"
    };
}

要查找的模拟代码mockRepo.Setup(repo => repo.Reservations.this).Returns(Single());。我得到编译错误。所以请帮我修复它。

解决方法

为了重新创建所需的行为,您可以在 Returns 中捕获传递的参数并使用它来创建假模型

[Fact]
public void Should_GET_AReservation_By_Id() {
    // Arrange
    var mockRepo = new Mock<IRepository>();
    mockRepo.Setup(repo => repo[It.IsAny<int>()])
        .Returns((int id) => Single(id));

    var controller = new ReservationController(mockRepo.Object);
    int id = 123456

    // Act
    ActionResult<Reservation> result = controller.Get(id);
    Reservation actual = result.Value;

    // Assert
    actual.Should().NotBeNull();
    actual.Id.Should().Be(id);
}

private static Reservation Single(int id) =>
    return new Reservation() {
        Id = id,Name = "Test One",StartLocation = "SL1",EndLocation = "EL1"
    };

注意使用 It.IsAny<int> 参数匹配器来接受传递给索引器的任何整数。

,

这可能对您有用:

mockRepo
    .SetupSet(repo => repo[123456] = It.IsAny<int>())
    .Callback((string name,object m) => {Single()});

来源:https://weblogs.asp.net/bleroy/mocking-indexer-setters-with-moq

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 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元字符(。)和普通点?