首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >当存在"this“关键字时如何使用xUnit和Moq测试web方法

当存在"this“关键字时如何使用xUnit和Moq测试web方法
EN

Stack Overflow用户
提问于 2021-01-17 14:21:39
回答 2查看 65关注 0票数 1

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

Web接口

代码语言:javascript
复制
public interface IRepository
{
    IEnumerable<Reservation> Reservations { get; }
    Reservation this[int id] { get; }
}

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

Web控制器

代码语言:javascript
复制
[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提供内存记录,而不是数据库记录.有一个类Repository.cs,它包含硬编码的记录。

代码语言:javascript
复制
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方法Get(int id),但不能因为'this‘关键字。我尝试了下面的代码,但失败了。

代码语言:javascript
复制
[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());。我得到编译错误。所以请帮我修一下。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2021-01-17 15:44:13

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

代码语言:javascript
复制
[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>参数匹配器接受传递给索引器的任何整数。

票数 2
EN

Stack Overflow用户

发布于 2021-01-17 15:20:29

这可能对你有用:

代码语言:javascript
复制
mockRepo
    .SetupSet(repo => repo[123456] = It.IsAny<int>())
    .Callback((string name, object m) => {Single()});

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

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/65761731

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档