模拟 DbProviderFactory
我对单元测试相对较新,对模拟也完全陌生。我有一个数据库类,它包装了 DbProvider 工厂,我想在不连接到数据库的情况下为其创建单元测试。
我将如何模拟 DbProvider 工厂,以便我可以将其传递来测试我的类?我还需要模拟 DbConnection、DbCommand 等吗?我的代码的一个小示例如下:
public Database(DbProviderFactory dbProviderFactory) {
Provider = dbProviderFactory;
}
public int UpdateRecords(string sql, CommandType type, params DbParameter[] parameters) {
int numberOfRecordsUpdated;
using (var connection = CreateConnection()) {
// Add ConnectionString
connection.ConnectionString = ConnectionString;
// Create command to hold the update statment
using (var command = CreateCommand()) {
try {
command.Connection = connection;
command.CommandType = type;
command.CommandText = sql;
// Add Parameters
foreach (var parameter in parameters) {
command.Parameters.Add(parameter);
}
// Open Connection
connection.Open();
// Execute SQL
numberOfRecordsUpdated = command.ExecuteNonQuery();
} finally {
command.Parameters.Clear();
}
}
}
return numberOfRecordsUpdated;
}
I am relatively new to unit testing, and completely new to mocking. I have a database class that wraps the DbProvider factory that I would like to create unit tests for without connecting to the database.
How would I mock the DbProvider factory, so I could pass it in to test my class? Would I also need to mock the DbConnection, DbCommand, etc.? A small sample of my code follows:
public Database(DbProviderFactory dbProviderFactory) {
Provider = dbProviderFactory;
}
public int UpdateRecords(string sql, CommandType type, params DbParameter[] parameters) {
int numberOfRecordsUpdated;
using (var connection = CreateConnection()) {
// Add ConnectionString
connection.ConnectionString = ConnectionString;
// Create command to hold the update statment
using (var command = CreateCommand()) {
try {
command.Connection = connection;
command.CommandType = type;
command.CommandText = sql;
// Add Parameters
foreach (var parameter in parameters) {
command.Parameters.Add(parameter);
}
// Open Connection
connection.Open();
// Execute SQL
numberOfRecordsUpdated = command.ExecuteNonQuery();
} finally {
command.Parameters.Clear();
}
}
}
return numberOfRecordsUpdated;
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
集成测试
如果您有兴趣(根据您的评论判断)测试从数据库获取数据,您将执行
集成测试
。这些类型的测试与单元测试的区别在于它们运行的频率较低 - 最佳实践要求您在提交源代码控制之前运行这些测试。
原因是它们速度较慢,并且您将访问真实的数据库(至少是测试数据库)。每次运行时,您都需要擦除数据库或不提交更改 - 您似乎知道自己在做什么,所以我将让您自己决定如何处理此问题。
嘲笑
至于测试使用数据库的逻辑 - 模拟和依赖注入是可行的方法。
我使用 Moq - 它可能是最容易使用的模拟框架。它实际上不仅仅适用于模拟对象(尽管名称如此),您还可以生成存根和假货 有了它。
伪模拟如下(使用数据库示例):
如需进一步帮助 - 检查 Google - 有一些用于单元测试和模拟的好资源。
Integration Testing
If you are interested (as judging by your comment) in testing getting data from the database you will be performing an
integration test
.The difference to
unit testing
for these types of test are they are run less often - best practice dictates you run these before committing to source control.The reason being they are slower and you will be hitting a real database (a test database at least). On each run you will need to wipe the database or not commit the changes - you seem to know what you're doing here so I'll leave how you handle this up to yourself.
Mocking
As for testing your logic that uses the database -
mocking
anddependency injection
is the way to go.I use Moq - its probably the easiest mocking framework to use. It actually isn't just for mock objects (despite the name) and you can produce stubs and fakes with it.
Pseudo mocking goes like this (using a DB example):
For further help - check Google - there are some good resources out there for unit testing and mocking.
我个人会模拟包含更高级别数据访问功能(如 UpdateRecords 等)的类,并使用此模拟返回预定的数据集。
DbProvider 和相应的 DbCommand 等的使用是数据访问层的实现细节,与使用返回值的更高级别功能并不真正相关。
I would personally mock the class that contains the higher level data access functionality (like UpdateRecords etc) and use this mock to return the predetermined datasets.
The use of DbProvider and the corresponding DbCommand etc are an implementation detail of your data access layer and not really relevant to the higher level functionality that uses the returned values.
数据访问类都是关于与数据库集成的。例如,Roy Osherove 在单元测试时认为此类是一个例外。我也对如何测试此类代码感兴趣。问题+1。
IOW 我不确定是否建议模拟数据访问类。
单元测试时不应该测试什么?< /a>
Data access classes are all about integrating with DB. Roy Osherove for example consider this classes an exception when unit testing. I'm interested too on how to test this type of code. +1 for question.
IOW I'm not sure that it's advisable to mock around data access classes.
What not to test when it comes to Unit Testing?