Reputation: 10055
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.
[TestMethod()]
public void TestMyWork()
{
MyWork work = new MyWork();
int result = work.DoWork();
Assert.AreEqual(1, result);
}
Upvotes: 2
Views: 54
Reputation: 14896
First, follow @toadflakz advice and inject MyData
to MyWork
's constructor.
Then, use some ORM to map the data from the db to objects. Don't use DataTable
.
To make DoWork
easier to test, consider refactoring it into a pure function:
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.
Upvotes: 1
Reputation: 7944
Make the MyData
class a dependency parameter and inject it during construction of your MyWork
class. 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.
More on Wikipedia: SOLID (OO design)
Edit:
Your unit test would then look something like (assuming you're using the Moq mocking framework):
[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):
var myWork = new MyWork(new MyData());
Upvotes: 5