简体   繁体   English

从 ICollection 继承的接口的最小起订量返回 null

[英]Moq for Interface that Inherits from ICollection returns null

I am trying to run unit tests using Moq.我正在尝试使用 Moq 运行单元测试。 I am fairly new to Moq and I have ran into a problem with this current unit test.我对最小起订量相当陌生,并且在当前的单元测试中遇到了问题。 I have a controller that is fetching some items.我有一个控制器正在获取一些项目。 The result is encapsulated within a generic interface using ICollection .结果使用ICollection封装在通用接口中。

public interface IResult
{
}

public interface IListResult : ICollection<IResult>
{
}

My controller is simply calling a method that returns the result.我的控制器只是调用一个返回结果的方法。

[HttpGet("get/{userId}/{pageSize}/{fetchNext}")]
public IActionResult GetConversations(int userId, int pageSize, bool fetchNext)
{
    try
    {
        GetConversationsByUserIdQuery query = new GetConversationsByUserIdQuery()
        {
            UserId = userId,
            PageSize = pageSize,
            FetchNext = fetchNext
        };
        var result = _mediator.GetConversationsByUserId(query);
        return Ok(result);
    }
    catch (Exception ex)
    {
        return StatusCode(StatusCodes.Status500InternalServerError, ex.Message);
    }
  }
}

When I am running my unit test, the result always comes back null and I am failing to understand what I am missing in my set up.当我运行单元测试时,结果总是返回 null,我无法理解我在设置中缺少什么。

[Theory]
[InlineData(1, 2 , false)]
[InlineData(1, 2 , true)]
public async void When_AddMessageToNewConversation_ThenSuccessfullyAdd(int userId, int pageSize, bool fetchNext)
{
    // Arrange
    Mock<IMessageMediator> _mediator = new Mock<IMessageMediator>();
    Mock<IListResult> _listResult = new Mock<IListResult>();
    
    GetConversationsByUserIdQuery query = new GetConversationsByUserIdQuery()
    {
        UserId = userId,
        PageSize = pageSize,
        FetchNext = fetchNext
    };


    List<Conversation> expected = new List<Conversation>()
    {
        new Conversation()
        {
            Id = Guid.NewGuid(),
            Created_At = DateTimeOffset.Now
        }
    };

    _listResult.Setup(x => 
        x.GetEnumerator())
        .Returns(expected.GetEnumerator());

    GetConversationsByUserIdController controller = new GetConversationsByUserIdController(_mediator.Object);
    _mediator.Setup(x => 
        x.GetConversationsByUserId(query)).Returns(_listResult.Object);

    // Act
    IActionResult result = controller.GetConversations(userId, pageSize, fetchNext);

    // Assert
    Assert.True(result is OkResult);
}

The IMessageMediator is simply a delegator that handles implementation of queriers and commands. IMessageMediator 只是一个处理查询器和命令实现的委托器。 The IListResult is returned from a querier handler. IListResult 从查询器处理程序返回。

public class GetConversationsByUserIdQueryHandler: 
IQueryHandler<GetConversationsByUserIdQuery>
{
   private IRepository<Conversations_By_UserId> 
  _conversationByUserIdRepository;
  private IListResult _result;

public GetConversationsByUserIdQueryHandler(IRepository<Conversations_By_UserId> conversationByUserIdRepository,
    IListResult result)
{
    _conversationByUserIdRepository = conversationByUserIdRepository;
    _result = result;
}

public IListResult Handle(GetConversationsByUserIdQuery query)
{
    IEnumerable<Conversations_By_UserId> conversations = _conversationByUserIdRepository
        .Get(query.PageSize,
            query.FetchNext,
            message => message.UserId == query.UserId).ToList();
    
    if (conversations.Any())
    {
        foreach (Conversations_By_UserId m in conversations)
        {
            _result.Add(new Conversation()
            {
                Created_At = m.Created_At,
                Id = m.Id,
            });
        }
    }
    return _result;
  }
}

You don't need to mock both IMessageMediator and IListResult .您不需要同时模拟IMessageMediatorIListResult

You should mock dependencies - it is IMessageMediator in your case - and your can setup it to return any result.您应该模拟依赖项-在您的情况下是IMessageMediator并且您可以将其设置为返回任何结果。

The other thing - you mock _mediator using query created in test, but in controller you create different query (references are different) and it is the reason of null result.另一件事-您使用在测试中创建的查询来模拟_mediator ,但是在控制器中您创建了不同的查询(引用不同),这是null结果的原因。

Change your test:改变你的测试:

[Theory]
[InlineData(1, 2 , false)]
[InlineData(1, 2 , true)]
public async void When_AddMessageToNewConversation_ThenSuccessfullyAdd(int userId, int pageSize, bool fetchNext)
{
    // Arrange
    Mock<IMessageMediator> _mediator = new Mock<IMessageMediator>();     

    List<Conversation> expected = new List<Conversation>()
    {
        new Conversation()
        {
            Id = Guid.NewGuid(),
            Created_At = DateTimeOffset.Now
        }
    };    
      
    GetConversationsByUserIdController controller = new GetConversationsByUserIdController(_mediator.Object);

             // It.IsAny<GetConversationsByUserIdQuery>()) instead of query
   _mediator.Setup(x => x.GetConversationsByUserId(It.IsAny<GetConversationsByUserIdQuery>()))

            // create fake result to return from mediator (no need to mock IListResult     
            .Returns(new ListResult() ...); // just create instance of IListResult with needed values

    // Act
    IActionResult result = controller.GetConversations(userId, pageSize, fetchNext);

    // Assert
    Assert.True(result is OkResult);
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM