FakeItEasy ControllerTest HttpGet调用

问题描述 投票:0回答:1

我想开始使用FakeItEasy来测试查询。我要编写的测试应该检查是否在HttpGet调用中返回了实体(获取所有内容并通过ID获取)

控制器:

public class ToDoController : ControllerBase
  {
    private readonly IMediator _mediator;

    public ToDoController(IMediator mediator) =>
    _mediator = mediator;

    [HttpGet]
    [Produces("application/json")]
    [ProducesResponseType(typeof(IEnumerable<ToDoItem>), (int)HttpStatusCode.OK)]
    public async Task<ActionResult<IEnumerable<ToDoItem>>> Get()
    {
        var result = await _mediator.Send(new ToDoItemsQuery(new 
                         AllToDoItems())).ConfigureAwait(false);

        if (result != null && result.Any())
        {
            return result.ToList();
        }

        throw new InvalidOperationException("TODO: error handling");
    }

    [HttpGet]
    [Route("{id}")]
    [Produces("application/json")]
    [ProducesResponseType(typeof(ToDoItem), (int)HttpStatusCode.OK)]
    public async Task<ActionResult<ToDoItem>> GetById(int itemId)
    {
      var result = await _mediator
        .Send(new ToDoItemsQuery(new ToDoItemById(itemId)))
        .ConfigureAwait(false);

      if (result != null && result.Any())
      {
        return result.FirstOrDefault(); 
      }

      throw new InvalidOperationException("TODO: error handling");
    }
  }
}

TestClass:

public class ToDoItemControllerTests : ControllerTestBase
{
  private IMediator _mediator;

  private ToDoController _sut;

  public ToDoItemControllerTests()
  {
    _mediator = A.Fake<IMediator>();
    _sut = new ToDoController(_mediator);
  }

  [TestMethod]
  public async Task GetAllItemsAsync_SuccessTest()
  {
    A.CallTo(() => _mediator.Send(A<AllToDoItems>._, 
           A<CancellationToken>._)).Returns(A.CollectionOfFake<ToDoItem>(10));
    var result = await _sut.Get();

    Assert.IsNotNull(result);
    A.CallTo(() => _mediator).MustHaveHappened();
  }

  [TestMethod]
  public async Task GetItemByIdAsync_SuccessTest()
  {
    // Arrange
    int itemId = 2;
    var commandResult =
      new List<ToDoItem>
      {
        new ToDoItem
        {
          Id = itemId        
        };
      }

    A.CallTo(() => MediatR.Send(A<ToDoItemById>._, A<CancellationToken>._)).Returns(commandResult);

    // Act
    var result = await _sut.GetById(itemId);

    // Assert
    Assert.IsNotNull(result);
    A.CallTo(() => MediatR.Send(A<ToDoItemById>._, A<CancellationToken>._)).MustHaveHappened();
  }
}

因此,在第一个测试中,我将IMediatR接口的A.CallTo设置为返回10个ToDoItems。在调试过程中,我看到_sut.Get()进入控制器,输入正确的方法/ api调用。控制器中的_mediator.Send()返回假IEnumerable(不是我在测试方法的第一个Call.To中设置的10个项目,但是没有任何结果的枚举)。

由于result.Any()为假,控制器将引发InvalidOperationException而且我什至无法断言结果。IsNotNull()

调用API后,我要测试是否要返回1的第二项测试。我为参数设置(a)一个类型为int的itemId,(b)清单中有1个项目的模拟(?)列表,其中有itemId和(c)对mediaR的调用应从(b)

返回模拟的List

我从测试中进行呼叫,在调试中,我看到呼叫正在等待_mediator.Sent()返回Fake Ienumerable of ToDoItem,结果不为null,而是因为result.Any()为false,该项目没有退货,而我又收到另一个InvalidOperationException

我觉得我在测试设置中缺少一些东西。伪数据库接口?我不想碰碰我的控制器,如果没有那么严格的限制,只是为了让我的测试通过]

编辑:即使我将if条件更改为删除Any条件我看到测试进入控制器,返回结果的“ First or Default”,该测试在发生“必须致电”时失败。期望找到一次或多次,但是没有调用该假对象。我真的不知道,我实际上看到他打了电话?!

我浏览了GitHub以查找示例,但我发现最接近的是带有方法的实体,这些方法在接口中定义。这里不是这种情况

[看似官方文档并没有使我更明智,所以转向<3预先感谢!

我想开始使用FakeItEasy来测试查询。我要编写的测试应该检查是否在HttpGet调用上返回了实体(获取所有内容并通过ID获取)控制器:public class ...

testing asp.net-core-3.0 mediator fakeiteasy mediatr
1个回答
0
投票

在第一个测试中,使用类型为Send的自变量配置对AllToDoItems的调用。但是,在控制器中,实际上是使用Send来调用TodoItemsQuery。因此,该调用不匹配,并且适用于默认(未配置)行为,该行为将返回伪造的IEnumerable。您需要这样配置呼叫:

© www.soinside.com 2019 - 2024. All rights reserved.