我试图熟悉TDD概念,并编写了第一个测试,其"行为"部分看起来像这样:
repositoryStub = new Mock<IMyRepository>();
var sut = new MyController(repositoryStub.Object);
var result = sut.Index() as ViewResult;
我最终实例化的控制器(MyController
)在创建视图模型时使用ConfigurationManager.AppSettings
。在试图从Web读取的行上,控制器的实例化失败。但是,显然,如果项目只是从IDE运行,则按预期运行。我正在阅读一个常量从web。配置文件,这应该不会影响测试,它不希望它会失败,一旦从另一个(MyProject.Test
)项目调用。
我对你们的问题是如何克服这个障碍?
我不知道这里是否重要,但以防万一,我使用xUnit
进行TDD。谢谢!
您需要意识到您在底层使用的配置与IMyRepository
是同一种依赖关系。您通过抽象契约(接口)注入存储库。为什么对配置不做同样的事情?快速而天真的解决方案是创建IConfiguration
接口,并通过简单地将调用委托给ConfigurationManager
来实现它。你的构造函数看起来像这样:
public class MyController(IMyRepository repository, IConfiguration configuration)
这告诉我们什么?不幸的是,没有多少。控制器需要配置的事实是非常模糊的。真正的问题是,它需要的配置中的确切的参数是什么?你需要确定那个参数,那才是你想要注入的真正依赖。考虑:
-
MyController(IMyRepository repository, IConfiguration configuration)
-
MyController(IMyRepository repository, int serviceCallTimeoutSeconds)
-
MyController(IMyRepository repository, string serviceAccessKey)
哪一个更好地传达了它的目的?你的控制器越是面向单一功能,它应该使用的参数就越少。你的问题可能不在你想的地方。