我有一个类,它有以下实现:
public sealed class HotelRepository : IHotelRepository
{
private readonly string _dataSource;
public HotelRepository(string dataSource) => _dataSource = dataSource;
/// <inheritdoc />
public async Task<IEnumerable<Hotel>> GetAllAsync() =>
await Task.Run(() => JObject.Parse(File.ReadAllText(_dataSource))["hotels"].ToList().Select(x => x.ToObject<Hotel>()));
/// <inheritdoc />
public async Task<IEnumerable<Hotel>> GetListByMatchAsync(string name) =>
await GetAllAsync().ContinueWith(x => x.Result.Where(y => y.Name.Contains(name, StringComparison.CurrentCultureIgnoreCase)));
}
如您所见,GetListByMatchAsync
方法调用GetAllAsync
,然后在返回结果之前执行一些逻辑。
当我试图模拟这个存储库进行单元测试时,我很难从GetListByMatchAsync
中获得结果,因为它总是作为空引用异常而失败。
以下是单元测试:
[TestCase("Test", "X")]
[TestCase("Hotel", "X")]
[TestCase("Name", "X")]
public async Task GetListByMatchAsync_GetHotelListByMatchingNameAsync_ReturnsFiveMatchingHotels(string name, string nonMatch)
{
_hotelRepositoryMock = new Mock<IHotelRepository>();
_hotelRepository = _hotelRepositoryMock.Object;
// Set up sample data.
var data = new List<Hotel>
{
new Hotel{Id = 1, Name = $"{name}", Description = "Description2", Location = "Location2", Rating = Rating.Two},
new Hotel{Id = 2, Name = $"{name.ToUpper()}", Description = "Description1", Location = "Location1", Rating = Rating.Five},
new Hotel{Id = 3, Name = $"{name.ToLower()}", Description = "Description2", Location = "Location2", Rating = Rating.Three},
new Hotel{Id = 4, Name = $"{name} {nonMatch}", Description = "Description2", Location = "Location2", Rating = Rating.One},
new Hotel{Id = 5, Name = nonMatch, Description = "Description2", Location = "Location2", Rating = Rating.One},
};
// Set up mock methods and ensure these method returns any sample data.
_hotelRepositoryMock.Setup(x => x.GetListByMatchAsync(It.IsAny<string>()));
_hotelRepositoryMock.Setup(x => x.GetAllAsync()).ReturnsAsync(data);
var result = await _hotelRepository.GetListByMatchAsync(name);
// Cast to list to make assertions.
var hotels = result.ToList();
Assert.That(hotels, Is.TypeOf<List<Hotel>>());
Assert.That(hotels.Count, Is.EqualTo(4));
}
如何使此测试工作,使GetListByMatchAsync
模拟方法在调用被模拟的GetAllAsync
方法之后执行一些逻辑?
首先,您所展示的代码可能无法工作,因为您试图设置的方法不是虚拟的。将要设置
的方法声明为虚拟
。
第二,这是错误的:
_hotelRepositoryMock.Setup(x => x.GetListByMatchAsync(It.IsAny<string>()));
通过此调用,您可以有效地将GetListByMatchAsync
设置为返回Default(Task
,即Null
。那显然不是你想要的。其中之一:
.returns(...)
指定方法应返回的内容;或,.callBase()
。(这可能是您需要的。)我想mock接受对象参数的方法。此对象参数是从动态创建的。不会返回预期的结果,尽管这两个对象具有相同的数据,但只是不同的哈希代码。 有没有什么方法来模拟方法,使它能够以预期的结果响应?
如何模拟返回已强制转换的模拟对象的方法。 试验方法。
我调用了一个方法,它连接到另一个服务器,每次调用它,它都返回不同的数据。 我正在为调用该方法的类编写一个单元测试。我已经嘲笑了那个类,我希望它返回存根结果。它实际上使用工作,但是它每次都返回相同的数据。我希望它返回不同的数据,我希望能够指定它应该是什么。 我试着使用“doReturn-when”,它可以工作,但我无法让它返回不同的结果。我不知道怎么做。 我还尝试使用“when-thenReturn
有一个方法
上面还有第二个问题。当我在Expects块中定义mock类时(如上),似乎只调用了构造函数,而不是,因此没有正确初始化对象。我通过将它移到方法中并在那里实例化该类来解决这个问题。看起来是这样的: 因此,这似乎得到了要调用的正确构造函数,但似乎还在调用。有什么见解吗?
我有一个方法,我需要写单元测试用例。该方法返回类型。