我正在尝试用xUnit和Moq测试web方法,但是出现了一种情况,因为它使用的是"this“关键字。请看密码。
Web接口
public interface IRepository
{
IEnumerable<Reservation> Reservations { get; }
Reservation this[int id] { get; }
}有一个关键字Reservation this[int id] { get; }
Web控制器
[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,它包含硬编码的记录。
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‘关键字。我尝试了下面的代码,但失败了。
[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());。我得到编译错误。所以请帮我修一下。
发布于 2021-01-17 15:44:13
为了重新创建所需的行为,可以在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>参数匹配器接受传递给索引器的任何整数。
发布于 2021-01-17 15:20:29
这可能对你有用:
mockRepo
.SetupSet(repo => repo[123456] = It.IsAny<int>())
.Callback((string name, object m) => {Single()});来源:https://weblogs.asp.net/bleroy/mocking-indexer-setters-with-moq
https://stackoverflow.com/questions/65761731
复制相似问题