我试图使用 xUnit
编写单元测试,针对的是使用 Dapper
从 Sqllite
数据库获取数据的 EntityService
类。在我的单元测试中,它总是返回实际值作为 List<Entity> []
,导致测试失败。我不明白我漏掉了什么。
测试类
public class EntityServiceTests
{
private readonly IEntityService _sut;
private readonly Mock<IEntityService> _entityServiceMock;
public EntityServiceTests()
{
_entityServiceMock = new Mock<IEntityService>();
var dapperMock = new Mock<IDapperWrapper>();
_sut = new EntityService(dapperMock.Object);
}
[Fact]
public void GetEntities_ShouldReturnEntities()
{
//Arrange
var expectedEntities = new List<Entity>
{
new()
{
Id = 1,
Name = "Test",
X = 12,
Y = 14.5,
CoordId = 1
},
new()
{
Id = 2,
Name = "Test2",
X = 16,
Y = 18.5,
CoordId = 2
}
};
var query = @"SELECT ent.*, crd.x, crd.y, crd.id as CoordId
FROM entities ent
INNER JOIN coords crd ON crd.entityId = ent.Id";
_entityServiceMock.Setup(x => x.GetEntities(0)).Returns(expectedEntities);
//Act
var entities = _sut.GetEntities(0).ToList();
//Assert
Assert.Equal(expectedEntities, entities);
}
}
服务类
public class EntityService : IEntityService
{
private readonly IDapperWrapper _dapperWrapper;
public EntityService(IDapperWrapper dapperWrapper)
{
_dapperWrapper = dapperWrapper;
}
public IEnumerable<Entity> GetEntities(int entityId)
{
var query = @"SELECT ent.*, crd.x, crd.y, crd.id as CoordId
FROM entities ent
INNER JOIN coords crd ON crd.entityId = ent.Id ";
if (entityId > 0)
{
query += " WHERE ent.id = @id";
var entities = _dapperWrapper.Query<Entity>(query, new { id = entityId });
return entities;
}
else
{
var entities = _dapperWrapper.Query<Entity>(query);
return entities;
}
}
}
Dapper包装类
public class DapperWrapper : IDapperWrapper
{
private IDbConnection Connection { get; }
public DapperWrapper()
{
Connection = new SQLiteConnection(GetConnectionString("ConnectionString"));
}
private string GetConnectionString(string name)
{
return ConfigurationManager.ConnectionStrings[name].ConnectionString;
}
public IEnumerable<T> Query<T>(string query)
{
return Connection.Query<T>(query);
}
public IEnumerable<T> Query<T>(string query, object param)
{
return Connection.Query<T>(query, param);
}
public T QuerySingle<T>(string query, object param)
{
return Connection.QuerySingle<T>(query, param);
}
}
通常项目运行良好,但在测试中失败。我认为我缺少某些基础但至关重要的东西。
更新:我现在使用了这段代码,但仍然收到失败的结果。
[Fact]
public void GetEntities_Should_Return_All_Entities_If_0_Is_Provided_In_Param()
{
//Arrange
var expectedEntities = new List<Entity>
{
new()
{
Id = 1,
Name = "Test",
X = 12,
Y = 14.5,
CoordId = 1
},
new()
{
Id = 2,
Name = "Test2",
X = 16,
Y = 18.5,
CoordId = 2
}
};
var query = @"SELECT ent.*, crd.x, crd.y, crd.id as CoordId
FROM entities ent
INNER JOIN coords crd ON crd.entityId = ent.Id ";
var dapperMock = new Mock<IDapperWrapper>();
dapperMock.Setup(x => x.Query<Entity>(query)).Returns(expectedEntities);
var sut = new EntityService(dapperMock.Object);
//Act
var entities = sut.GetEntities(0);
//Assert
Assert.Equal(expectedEntities, entities);
}
_entityServiceMock.Setup(x => x.GetEntities(0)).Returns(expectedEntities);
我在这里使用它来设置模拟和期望值。 - Rao ArmandapperMock.Setup(x => x.Query<Entity>(It.IsAny<string>())).Returns(expectedEntities);
。据我理解,Moq只有在使用完全相同的字符串引用查询时才会返回。但是你的测试仍然没有太大价值。 - Palle Duevar entities = sut.GetEntities(0);
当我调试时,我看到一切都运行良好,但是当查询执行时,它返回了空值。我无法理解为什么... - Rao Arman