[英]Mocking an implementation class with test class within unit test in C#
I'm trying to write a simple unit test where I have wrapped the HttpContext.Current.Server.MapPath with an interface and implementation. 我正在尝试编写一个简单的单元测试,其中已使用接口和实现包装了HttpContext.Current.Server.MapPath。 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);
}
There are a few options. 有一些选择。
In general, you want your FooProvider
to have a IPathProvider
instead of ServicePathProvider
as its servicePathProvider
member variable. 通常,您希望FooProvider
拥有一个IPathProvider
而不是ServicePathProvider
作为其servicePathProvider
成员变量。
You can have two constructors for FooProvider
: 您可以为FooProvider
提供两个构造FooProvider
:
servicePathProvider = new ServicePathProvider();
实例化servicePathProvider = new ServicePathProvider();
默认构造函数servicePathProvider = new ServicePathProvider();
, and 和 IServiceProvider
as an argument and sets servicePathProvider
to that. 实例化的非默认构造函数接受IServiceProvider
作为参数,并将servicePathProvider
设置为该参数。 Change FooProvider
as follows: 如下更改FooProvider
:
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>
. 在非单元测试代码中,您将使用FooProvider<ServicePathProvider>
;对于单元测试,您将使用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. 这使得FooProvider
接受通用类型T
,它是IServiceProvider
的子类型, 并且在where子句中具有默认构造函数(即new()
部分)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.