I have 2 classes:
SecondDeep.cs
I did simple code for example:
class FirstDeep
{
public FirstDeep() { }
public string AddA(string str)
{
SecondDeep sd = new SecondDeep();
bool flag = sd.SomethingToDo(str);
if (flag == true)
str = string.Concat(str, "AAA");
else
str = string.Concat(str, "BBB");
return str;
}
}
and
class SecondDeep
{
public bool SomethingToDo(string str)
{
bool flag = false;
if (str.Length < 10)
{
//todo something in DB, and after that flag should be TRUE
}
return flag;
}
}
Then I want to write unit test for method "AddA":
class Tests
{
[Test]
public void AddATest()
{
string expected = "ABCAAA";
FirstDeep fd = new FirstDeep();
string res = fd.AddA("ABC");
Assert.AreEqual(expected, res);
}
}
And after that I have trouble, I don't know how correct write stub for method SomethingToDo in my Test class. I always have false. I should just return TRUE. But how?
A good way to allow you to write stubs is to use dependency injection. FirstDeep
depends on SecondDeep
and in your test you want to replace SecondDeep
with a stub.
First change your existing code by extracting an interface for SecondDeep
and then inject that into FirstDeep
in the constructor:
interface ISecondDeep {
Boolean SomethingToDo(String str);
}
class SecondDeep : ISecondDeep { ... }
class FirstDeep {
readonly ISecondDeep secondDeep;
public FirstDeep(ISecondDeep secondDeep) {
this.secondDeep = secondDeep;
}
public String AddA(String str) {
var flag = this.secondDeep.SomethingToDo(str);
...
}
}
Note that FirstDeep
no longer creates a SecondDeep
instance. Instead an instance is injected in the constructor.
In your test you can create a stub for ISecondDeep
where SomethingToDo
always returns true:
class SecondDeepStub : ISecondDeep {
public Boolean SomethingToDo(String str) {
return true;
}
}
In the test you use the stub:
var firstDeep = new FirstDeep(new SecondDeepStub());
In production code you use the "real" SecondDeep
:
var firstDeep = new FirstDeep(new SecondDeep());
Using a dependency injection container and a stubbing framework can make a lot of this easier to do.
If you don't want to rewrite your code you can use a framework for intercepting calls like Microsoft Moles. In the next version of Visual Studio a similar technology will be available in the Fakes Framework.