如何解决有“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 举报,一经查实,本站将立刻删除。