使用 Specflow 和 WatiN 进行 IOC (simpleServiceLocator) 设置测试

发布于 2024-12-26 07:12:52 字数 681 浏览 2 评论 0原文

我使用 Specflow 和 WatiN 进行了一些验收测试,但不确定在哪里为 IOC 容器 (SimpleServiceLocator) 设置注册。

在我的网站中,注册是通过 my global.asax 完成的。

在我的测试项目中,我尝试使用以下代码从我的 [BeforeScenario] 方法中设置它们

var container = new SimpleServiceLocator();
container.Register<ISitecoreLookupAccessor>(
    () => new SitecoreLookupAccessor());

Microsoft.Practices.ServiceLocation.ServiceLocator
    .SetLocatorProvider(() => container);

,并且我使用以下代码在我的应用程序项目中获取了一个对象实例,

ISitecoreLookupAccessor accessor =
    ServiceLocator.Current.GetInstance<ISitecoreLookupAccessor>();

但我收到错误“对象引用未设置为对象的实例。 ”因为 ServiceLocator.Current 为 null ...

I have some acceptance tests using Specflow and WatiN but am not sure where to setup up my registrations for my IOC container (SimpleServiceLocator).

In my web site, the registration is done my global.asax.

In my test project, I've tried setting them up from my [BeforeScenario] method with code such as

var container = new SimpleServiceLocator();
container.Register<ISitecoreLookupAccessor>(
    () => new SitecoreLookupAccessor());

Microsoft.Practices.ServiceLocation.ServiceLocator
    .SetLocatorProvider(() => container);

And I get an object instance in my application project using

ISitecoreLookupAccessor accessor =
    ServiceLocator.Current.GetInstance<ISitecoreLookupAccessor>();

But I get an error "Object reference not set to an instance of an object." as ServiceLocator.Current is null ...

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

故事和酒 2025-01-02 07:12:52

运行,因为您的测试运行程序无法知道它甚至应该考虑它们可能是 global.asax 的可能性:-)

Global.asax 是 ASP.NET 特定的,不会在您的测试项目中 换句话说,为了能够使用 ServiceLocator.Current,应该使用该测试项目的有效容器来调用 ServiceLocator.SetLocatorProvider。使用 MSTest 时,有一个 AssemblyInitializeAttribute 可用于修饰方法。在这种情况下,MSTest 将在执行该程序集中的任何测试方法之前运行该方法。其他测试运行程序有不同的机制来执行此操作。

但是,与其在测试项目中配置公共服务定位器,不如完全防止在测试中使用它。相反,将被测类的所有依赖项注入到其构造函数中,并在每个测试的设置阶段执行此操作(为了方便起见,您可以将此类被测对象的构造重构为特殊的工厂方法)。防止从被测类(或应用程序中的任何类)调用 ServiceLocator。这样就不需要在测试项目中使用 ServiceLocator。这将使编写测试变得更加容易,因为您不必在测试程序集中维护 DI 配置(并且对于多个测试项目,您将拥有多个 DI 配置)。我已经走了这条路,我的测试的 DI 配置变得非常复杂,特别是因为我必须处理并行运行测试的测试运行程序,这意味着我必须注入线程安全的模拟和存根(可怕的) !)。但即使没有并行运行测试,维护测试 DI 配置也是相当糟糕的。

The Global.asax is ASP.NET specific and will not run in your test project, because your test runner has no way of knowing that it should even consider the chance of having the possibility that their might be a global.asax :-)

In other words, for you to be able to use ServiceLocator.Current, the ServiceLocator.SetLocatorProvider should be called with a valid container for that test project. When using MSTest, there is an AssemblyInitializeAttribute that can be used to decorate a method. MSTest will in that case run that method before executing any of the test methods in that assembly. Other test runners have different mechanisms of doing this.

However, instead of configuring the Common Service Locator in your test projects, it is much better to prevent from using it completely in your tests. Instead inject all dependencies of a class under test in its constructor, and do that in the setup phase of each test (you can refactor the construction of such object under test to a special factory method for convenience). Prevent from calling the ServiceLocator from within the class under test (or any class in the application). This way there is no need of using the ServiceLocator in your test project. This will make writing tests so much easier, since you don't have to maintain the DI configuration in your test assemblies (and with multiple test projects, you would have had multiple DI configurations). I've walked this path and my DI configuration for my tests got horribly complex, especially since I had to deal with my test runner running my tests in parallel, which meant I had to inject mocks and stubs that were thread-safe (the horror!). But even without tests running in parallel, maintaining a test DI configuration is quite horrible.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文