[英]Unit Testing class which communicates with a database
Ok Lets assume i have a class which controls my data layer and a class which performs the work. 好的,假设我有一个控制我的数据层的类和一个执行工作的类。
class MyData
{
public DataTable GetMyData()
{
return Query.MyDataBase.ResultDT();
}
}
class MyWork
{
public int DoWork()
{
MyData Data = new MyData();
DataTable DT = Data.GetMyData();
return DT.Rows.Count;
}
}
How can i test my DoWork method with a unit test without accessing the database. 如何在不访问数据库的情况下使用单元测试来测试DoWork方法。
[TestMethod()]
public void TestMyWork()
{
MyWork work = new MyWork();
int result = work.DoWork();
Assert.AreEqual(1, result);
}
Make the MyData
class a dependency parameter and inject it during construction of your MyWork
class. 使
MyData
类成为依赖项参数,并在构造MyWork
类时将其注入。 For unit testing purposes, mock the dependency in your unit test to ensure that it is calling the defined dependency's contract in an expected manner. 为了进行单元测试,请在单元测试中模拟依赖项,以确保它以预期的方式调用已定义的依赖项合同。
Typically this means: 通常,这意味着:
As a final result, your code would be transformed as follows: 最终结果是,您的代码将进行如下转换:
interface IMyData
{
DataTable GetMyData();
}
class MyData : IMyData
{
public DataTable GetMyData()
{
return Query.MyDataBase.ResultDT();
}
}
class MyWork
{
private IMyData _myData;
public MyWork(IMyData myData)
{
_myData = myData;
}
public int DoWork()
{
DataTable DT = _myData.GetMyData();
return DT.Rows.Count;
}
}
As a step further, you should check out the SOLID design principles as this type of design demonstrates why they exist. 进一步,您应该检查SOLID设计原则,因为这种类型的设计说明了它们为什么存在。
More on Wikipedia: SOLID (OO design) 有关Wikipedia的更多信息:SOLID(面向对象设计)
Edit: 编辑:
Your unit test would then look something like (assuming you're using the Moq mocking framework): 然后,您的单元测试将类似于(假设您使用的是Moq模拟框架):
[TestMethod()]
public void TestMyWork()
{
var mockMyData = Mock<IMyData>();
mockMyData.Setup(x => x.GetMyData()).Returns(new DataTable());
MyWork work = new MyWork(mockMyData);
int result = work.DoWork();
Assert.AreEqual(1, result);
}
..but in the real world you would more than likely instantiate MyWork
with a real MyData
instance as follows (unless you're using a Dependency Injection framework such as MEF or Unity): ..但是在现实世界中,您很有可能按照如下所示使用真实的
MyData
实例实例化MyWork
(除非您使用的是Dependency Injection框架,例如MEF或Unity):
var myWork = new MyWork(new MyData());
First, follow @toadflakz advice and inject MyData
to MyWork
's constructor. 首先,遵循@toadflakz建议并将
MyData
注入MyWork
的构造函数中。
Then, use some ORM to map the data from the db to objects. 然后,使用一些ORM将数据从db映射到对象。 Don't use
DataTable
. 不要使用
DataTable
。
To make DoWork
easier to test, consider refactoring it into a pure function : 为了使
DoWork
易于测试,请考虑将其重构为一个纯函数 :
public int DoWork(DataTable dt)
{
// make some complex calculations on dt
}
This way the result of DoWork
depends only on the input parameter, which makes it very easy to test. 这样,
DoWork
的结果仅取决于输入参数,这使得测试非常容易。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.