【问题标题】:Setting up Mock repository with Moq使用 Moq 设置 Mock 存储库
【发布时间】:2019-08-04 12:43:12
【问题描述】:

我正在使用 xUnit 和 Moq 对控制器逻辑进行单元测试。我正在尝试使用可以使测试用例通过的模拟存储库对象。但是,在我的设置中,它导致测试失败,因为 Mock 存储库返回 null 而不是 TweetDay 对象。

我正在测试 TweetsController:

public class TweetsController : ControllerBase
{
    private readonly ITweetDayRepository _tweetDayRepository;

    public TweetsController(ITweetDayRepository tweetDayRepository)
    {
        //Implementation here
    }

    public async Task<IActionResult> GetTweetDay()
    {
            var tweet = await _tweetDayRepository.GetTweetOfTheDayAsync(_systemClock.GetToday);

            if (tweet == null)
            {
                _logger.LogError(LoggingEvents.GetItemNotFound, "An error occurred getting tweet with date: {Date}", _systemClock.GetToday);
                return BadRequest();
            }

            return Ok(tweet);
        }
        catch (Exception ex)
        {
            _logger.LogError(LoggingEvents.GetItemNotFound, ex, "An error occurred getting tweet with date: {Date}", _systemClock.GetToday);
            return BadRequest();
        }
    }
}

下面是我的测试用例:

public class TweetsControllerTests
{
    private Mock<IMemoryCache> _cache;
    private readonly Mock<IMapper> _mapper;
    private readonly Mock<ILogger<TweetsController>> _logger;
    private readonly Mock<ISystemClockService> _systemClock;
    //private readonly ITweetDayRepository _tweetDayRepository;

    public TweetsControllerTests()
    {
        _cache = new Mock<IMemoryCache>();
        _mapper = new Mock<IMapper>();
        _systemClock = new Mock<ISystemClockService>();
        _logger = new Mock<ILogger<TweetsController>>();
    }

    [Fact]
    public async Task GetTweetDay_ReturnsOkResult_WithATweetObject()
    {
        // Arrange
        var mockRepo = new Mock<ITweetDayRepository>();
        mockRepo.Setup(repo => repo.GetTweetOfTheDayAsync(DateTime.Today))
            .ReturnsAsync(GetTestTweet());

        var controller = new TweetsController(mockRepo.Object, _cache.Object, _logger.Object,
                                                 _systemClock.Object, _mapper.Object);

        // Act
        var result = await controller.GetTweetDay();

        // Assert
        var okResult = Assert.IsType<OkResult>(result);
    }

    private TweetDay GetTestTweet()
    {
        var tweet = new TweetDay()
        {
            Bird = new Bird(),
            BirdId = 0,
            CreationDate = new DateTime(2016, 7, 2),
            DisplayDay = new DateTime(2016, 7, 2),
            LastUpdateDate = new DateTime(2016, 7, 2),
            TweetDayId = 0
        };

        return tweet;
    }
}

根据我的设置,我希望 Mock 存储库返回初始化的 TweetDay 对象

mockRepo.Setup(repo => repo.GetTweetOfTheDayAsync(DateTime.Today))
    .ReturnsAsync(GetTestTweet());

我无法确定问题的确切根源。

我是否正确设置了 Mock 存储库?还是其他地方的问题?

【问题讨论】:

    标签: c# unit-testing asp.net-core moq xunit


    【解决方案1】:

    根据显示的设置,你们中的一个人注入了模拟依赖项(我怀疑是系统时钟)

     var tweet = await _tweetDayRepository.GetTweetOfTheDayAsync(_systemClock.GetToday);
    

    行为不符合预期,导致硬编码的 DateTime.Today 预期不匹配,因此返回 null 或与匹配器中使用的值不同的默认值。

    您可以通过放松目标模拟中的预期匹配来解决此问题

    mockRepo
    .Setup(repo => repo.GetTweetOfTheDayAsync(It.IsAny<DateTime>()))
    .ReturnsAsync(GetTestTweet());
    

    【讨论】:

      猜你喜欢
      • 2013-11-03
      • 1970-01-01
      • 2023-03-28
      • 1970-01-01
      • 1970-01-01
      • 2018-06-28
      • 1970-01-01
      • 1970-01-01
      • 2011-12-20
      相关资源
      最近更新 更多