Reputation: 177
I'm trying to write a simple unit test where I have wrapped the HttpContext.Current.Server.MapPath with an interface and implementation. I'm not positive if the implementation is in the right place.
public class FooGenerator
{
ServerPathProvider serverPathProvider = new ServerPathProvider();
public string generateFoo()
{
BarWebService bws = new BarWebService(serverPathProvider.MapPath("~/path/file"));
return stuff;
}
}
public class ServerPathProvider : IPathProvider
{
public string MapPath(string path)
{
return HttpContext.Current.Server.MapPath(path);
}
}
In the test I have my own implementation I want to use, but I cannot figure out how to inject this into the real class during the unit test.
[TestClass()]
public class FooGeneratorTests
{
[TestMethod()]
public void generateFooTest()
{
FooGenerator fg = new FooGenerator();
//Some kind of mock dependency injection
Mock<IPathProvider> provider = new Mock<IPathProvider>();
//stub ServerPathProvider object with provider mock
string token = fg.generateFoo;
Assert.IsNotNull(token);
}
}
public class TestPathProvider : IPathProvider
{
public string MapPath(string path)
{
return Path.Combine(@"C:\project\", path);
}
}
Finally, here is my interface just in case. Basically I just want to swap out two implementations depending on whether or not I am unit test. This is my first unit test so much of this is new to me. Sorry if I'm missing something basic, but I've been digging through stack overflow for a while now and can't find the steps to do this part.
public interface IPathProvider
{
string MapPath(string path);
}
Upvotes: 1
Views: 653
Reputation: 3769
There are a few options.
In general, you want your FooProvider
to have a IPathProvider
instead of ServicePathProvider
as its servicePathProvider
member variable.
You can have two constructors for FooProvider
:
servicePathProvider = new ServicePathProvider();
, andIServiceProvider
as an argument and sets servicePathProvider
to that.Change FooProvider
as follows:
public class FooProvider<T> where T : IServiceProvider, new()
In non-unit testing code, you would use FooProvider<ServicePathProvider>
and for unit tests, you would use FooProvider<Mock>
.
This makes FooProvider
accepts a generic type T
which is a subtype of IServiceProvider
and has a default constructor (that's the new()
part) in the where clause.
Upvotes: 1