Mock在设置时未按预期进行操作



我正在AuhtorRepository类的xUnit项目中测试一个名为GetAll的方法。

public class AuthorRepository : IAuthorRepository
{
private readonly ISqlDb _db;
public string Connection { get; set; }
public AuthorRepository(ISqlDb db)
{
_db = db;
}
public async Task<List<AuthorModel>> GetAll()
{
string sql = "SELECT * FROM Author";
List<AuthorModel> authors = await _db.LoadDataAsync<AuthorModel, dynamic>(sql, new { }, Connection);
return authors; 
}
}

在这个方法中使用的是LoadDataAsync方法,我将在测试中模拟它。

界面的结构如下所示。

public interface ISqlDb
{
Task<List<T>> LoadDataAsync<T, U>(string sql, U parameters, string connection);
}

最后实现了测试我的xUnit项目。

using Autofac.Extras.Moq;
using DataAccess.Library;
using Moq;
using Repository.Library.Models;
using Repository.Library.Repositories;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Xunit;
namespace RespositoryTests
{
public partial class AuhtorRepositoryTests
{
[Fact]
public async Task GetAll_ShouldWorkd()
{
using (var autoMock = AutoMock.GetLoose())
{
//Arrange
autoMock.Mock<ISqlDb>()
.Setup(x => x.LoadDataAsync<AuthorModel, dynamic>("SELECT * FROM Author", new { }, " "))
.ReturnsAsync(GetSamples());
//Act
var cls = autoMock.Create<AuthorRepository>();
cls.Connection = " ";
var expected = GetSamples();
var acutal = await cls.GetAll();
//Assert                
Assert.Equal(expected.Count, acutal.Count);
}
}
private List<AuthorModel> GetSamples()
{
var authors = new List<AuthorModel>();
authors.Add(new AuthorModel { Id = 1, FirstName = "first name", LastName = "lastname" });
authors.Add(new AuthorModel { Id = 3, FirstName = "Angela", LastName = "Merkel" });
return authors;
}
}
}

该项目的结构如下:[1] :https://i.stack.imgur.com/F4TPT.png

测试失败,出现以下语句:

消息:System.NullReferenceException:对象引用未设置为对象的实例。

所以我希望测试应该通过。

到目前为止我尝试过的:

->我用相同的代码写了一个类似的项目,唯一的区别是项目结构。每个接口和类都在同一个测试项目中,测试通过了。

而在我的BookApp解决方案中,ISqlDb适用于DataAccess.Library项目。

因此,在mocking中,ReturnAsync方法似乎没有返回值来自我的GetSamples。

请记住

  • a(这是我在stackoverflow和
  • b( 我试着迈出嘲笑的第一步

试用:

//Act
//var cls = autoMock.Create<AuthorRepository>();
//cls.Connection = "";
var cls = new AuthorRepository(autoMock.Create<ISqlDb>());
cls.Connection = "";
var expected = GetSamples();
var acutal = await cls.GetAll();
//Assert                
Assert.Equal(expected.Count, acutal.Count);

mock默认返回null,因为对mock成员的调用与设置不匹配。参考Moq Quickstart以更好地了解如何使用Moq。

这里需要使用参数匹配器,因为设置中使用的匿名new { }与测试时实际使用的引用不匹配

//...
autoMock.Mock<ISqlDb>()
.Setup(x => x.LoadDataAsync<AuthorModel, dynamic>("SELECT * FROM Author", It.IsAny<object>(), It.IsAny<string>()))
.ReturnsAsync(GetSamples());
//...

注意使用It.IsAny<object>()可以允许传入的任何内容。

有了上述变化,测试如期通过。

相关内容

  • 没有找到相关文章

最新更新