Dapper:unit testingSQL查询

我开始使用微型ORM的Dapper,我使用的是Dapper Rainbow。 我想测试查询和它们检索的数据。

我的意思是,例如,我有UserService和方法GetAll() ,我想测试sql查询是从一些列表中检索所有用户(而不是从数据库,因为我希望测试快速)。 你知道我怎么能这样做吗?

我的服务类(以及我想测试的方法):

public static class UserService{ public static IEnumerable GetAll(){ return DB.Users.All(); } } 

您对unit testing查询和数据检索有什么建议吗?

谢谢

我建议阅读dependency injection和存储库模式。 如果你采用上面代码中的方法,你将很难模拟出依赖关系,因为类和方法是静态的。

这是一个更好的方法。

 public interface IUserRepository { IEnumerable GetAll() } public class UserRepository : IUserRepository { public IEnumerable GetAll() { return DB.Users.All(); } } public class UserService { IUserRepository _userRepository; public UserService(IUserRepository userRepository) { _userRepository = userRepository } public Enumerable GetAll(){ return _userRepository.GetAll(); } } 

现在进行测试,您可以模拟您的存储库。 我使用了一个名为NSubstitute的模拟框架,在我看来它比上面提到的其他框架简单得多,但这是个人偏好。 首先,您可以在没有任何模拟框架的情况下编写测试。

 public class FakeUserRepository : IUserRepository { public IEnumerable GetAll() { return new List { new User {FirstName='Bob', LastName='Smith'}, }; } } 

在你的测试中

 [Test] public void GetAll_ShouldReturnAllFromFake() { // Arrrange var userService = new UserService(new FakeUserRepository()) // Act var result = userService.GetAll(); // Assert var user = result[0]; Assert.AreEqual("Bob", user.FirstName); Assert.AreEqual("Smith", user.LastName); } 

这个例子有点人为,因为测试你可以从假存储库中获取数据并没有多大意义。 你如何在现实中使用它是因为你的服务中有一些业务逻辑说回到用户然后检查它们是否比某个年龄或某些年龄大。 例如UserService上的IsLegalDrivingAge方法。

使用Dapper,您的SQL可能是字符串文字,可能与C#条件混合,语法未validation,DB引用可能错误。 你的测试直觉很好。 但是,针对真实数据库运行代码是判断它是否输出有效查询的唯一方法。 所以你需要的测试是集成测试。 这并不难,您可以使用unit testing框架来完成它,但由于测试必须访问真正的数据库,您可能不希望在运行unit testing的任何地方运行它,而不是在构建服务器上运行它。

然后,由于Dapper是ADO的扩展方法,要对使用查询的代码进行unit testing,您需要将其包装在存储库模式中。 Dapper Wrapper似乎是这里的工具。

如果所有这些看起来都不必要,请尝试QueryFirst (免责声明:我写了)。 您在一个真实的SQL窗口中编写SQL,连接到您的数据库,在您键入时validationsql。 每次保存文件时,您的查询都会针对您的数据库进行集成测试,而无需您抬起手指。 然后,如果查询运行,QueryFirst会生成包装器代码以允许您使用它,包括一个接口,这样您可以在unit testing使用代码时轻松模拟真实查询。 那必须向前迈进一步,不是吗?