使用 Moq 设置 Mock 存储库
Setting up Mock repository with Moq
我正在使用 xUnit 和 Moq 对控制器逻辑进行单元测试。我正在尝试使用 Mock 存储库对象,这将使测试用例能够通过。但是,在我的设置中,它导致测试失败,因为 Mock 存储库 returns 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 存储库 return TweetDay 对象在
中初始化
mockRepo.Setup(repo => repo.GetTweetOfTheDayAsync(DateTime.Today))
.ReturnsAsync(GetTestTweet());
我无法确定问题的确切根源。
我是否正确设置了 Mock 存储库?还是其他地方的问题?
根据显示的设置,你们其中之一注入了模拟依赖项(我怀疑系统时钟)
var tweet = await _tweetDayRepository.GetTweetOfTheDayAsync(_systemClock.GetToday);
未按预期运行并导致硬编码 DateTime.Today
期望不匹配,因此 return 为 null 或与匹配器中使用的默认值不同。
您可以通过放松目标模拟中的预期匹配来解决这个问题
mockRepo
.Setup(repo => repo.GetTweetOfTheDayAsync(It.IsAny<DateTime>()))
.ReturnsAsync(GetTestTweet());
我正在使用 xUnit 和 Moq 对控制器逻辑进行单元测试。我正在尝试使用 Mock 存储库对象,这将使测试用例能够通过。但是,在我的设置中,它导致测试失败,因为 Mock 存储库 returns 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 存储库 return TweetDay 对象在
中初始化mockRepo.Setup(repo => repo.GetTweetOfTheDayAsync(DateTime.Today))
.ReturnsAsync(GetTestTweet());
我无法确定问题的确切根源。
我是否正确设置了 Mock 存储库?还是其他地方的问题?
根据显示的设置,你们其中之一注入了模拟依赖项(我怀疑系统时钟)
var tweet = await _tweetDayRepository.GetTweetOfTheDayAsync(_systemClock.GetToday);
未按预期运行并导致硬编码 DateTime.Today
期望不匹配,因此 return 为 null 或与匹配器中使用的默认值不同。
您可以通过放松目标模拟中的预期匹配来解决这个问题
mockRepo
.Setup(repo => repo.GetTweetOfTheDayAsync(It.IsAny<DateTime>()))
.ReturnsAsync(GetTestTweet());