如何编写规范与MSpec为code,改变Thread.CurrentPrincipal中? [英] How to write specs with MSpec for code that changes Thread.CurrentPrincipal?

查看:175
本文介绍了如何编写规范与MSpec为code,改变Thread.CurrentPrincipal中?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经把一些旧的规范,以MSpec(均使用NUnit / SpecUnit)。该规范是一个视图模型,有问题的视图模型做了一些自定义的安全检查。我们有我们的规格为其中Thread.CurrentPrincipal中设置将伪造安全证书一个辅助方法。这工作得很好,在旧的单元测试,但未能在MSpec。具体来说,我得到这个异​​常:

I've been converting some old specs to MSpec (were using NUnit/SpecUnit). The specs are for a view model, and the view model in question does some custom security checking. We have a helper method in our specs which will setup fake security credentials for the Thread.CurrentPrincipal. This worked fine in the old unit tests, but fails in MSpec. Specifically, I'm getting this exception:

System.Runtime.Serialization.SerializationException:类型未解决的成员

"System.Runtime.Serialization.SerializationException: Type is not resolved for member"

它发生时,被测系统的一部分,试图读取应用程序配置文件。如果我注释掉这台CurrentPrincipal线(或仅仅是检查配置文件中的部分之后称呼它),错误消失,但测试失败归因于缺乏凭据。

It happens when part of the SUT tries to read the app config file. If I comment out the line which sets the CurrentPrincipal (or simply call it after the part that checks the config file), the error goes away, but the tests fail due to lack of credentials.

同样,如果我设置CurrentPrincipal为空,错误消失,但再次测试失败,因为凭据未设置。我GOOGLE了这一点,并发现关于确保定制的主体是序列化时,它跨越应用程序域边界(通常是在参考网络应用程序)的一些职位。就我们而言,这不是一个Web应用程序,而我没有越过任何应用程序域。我们pincipal对象也可序列化。

Similarly, if I set the CurrentPrincipal to null, the error goes away, but again the tests fail because the credentials aren't set. I've googled this, and found some posts about making sure the custom principal is serializable when it crosses AppDomain boundaries (usually in reference to web apps). In our case, this is not a web app, and I'm not crossing any AppDomains. Our pincipal object is also serializable.

我下载源MSpec,并发现该ConsoleRunner调用名为AppDomainRunner类。我还没有调试到它,但它看起来像它的运行在不同的应用程序域的规格。

I downloaded the source for MSpec, and found that the ConsoleRunner calls a class named AppDomainRunner. I haven't debugged into it, but it looks like it's running the specs in different app domains.

因此​​,没有人对我怎么能解决这个任何想法?我真的很喜欢MSpec,并会喜欢独占使用。不过,我需要能够在运行测试,以提供虚假的安全证书。

So does anyone have any ideas on how I can overcome this? I really like MSpec, and would love to use it exclusively. But I need to be able to supply fake security credentials while running the tests.

下面是规范类:

[Subject(typeof(CountryPickerViewModel))]
public class When_the_user_makes_a_selection : PickerViewModelSpecsBase
{
    protected static CountryPickerViewModel picker;

    Establish context = () =>
    {
        SetupFakeSecurityCredentials();
        CreateFactoryStubs();

        StubLookupServicer<ICountryLookupServicer>()
            .WithData(BuildActiveItems(new [] { "USA", "UK" }));

        picker = new CountryPickerViewModel(ViewFactory, ViewModelFactory, 
                                BusinessLogicFactory, CacheFactory);

    };

    Because of = () =>
        picker.SelectedItem = picker.Items[0];

    Behaves_like<Picker_that_has_a_selected_item> a_picker_with_a_selection;
}

我们有一些这些选择器视图模型,所有这些都表现出一些共同的行为。所以我使用MSpec的行为特征。这种特殊的类模拟用户选择从(WPF)控制其绑定到这个虚拟的东西。 该SetupFakeSecurityCredentials()方法简单地设置为Thread.CurrentPrincipal中我们自定义主体,其中prinipal已填充的意志完全访问权限的实例。

We have a number of these "picker" view models, all of which exhibit some common behavior. So I'm using the Behaviors feature of MSpec. This particular class is simulating the user selecting something from the (WPF) control which is bound to this VM. The SetupFakeSecurityCredentials() method is simply setting Thread.CurrentPrincipal to an instance of our custom principal, where the prinipal has been populated will full-access rights.

下面是一个假的CountryPickerViewModel这也足以导致错误:

Here's a fake CountryPickerViewModel which is enough to cause the error:

public class CountryPickerViewModel
{
    public CountryPickerViewModel(IViewFactory viewFactory, 
                IViewModelFactory viewModelFactory, 
                ICoreBusinessLogicFactory businessLogicFactory, 
                ICacheFactory cacheFactory)
    {
        Items = new Collection<int>();
        var validator = ValidationFactory.CreateValidator<object>();
    }

    public int SelectedItem { get; set; }
    public Collection<int> Items { get; private set; }

}

这是ValidationFactory调用它炸毁。 ValidationFactory是企业库对象,尝试访问配置。

It's the ValidationFactory call which blows up. ValidationFactory is an Enterprise Library object, which tries to access the config.

推荐答案

请参阅<一href="http://stackoverflow.com/questions/2326847/spec-fails-when-run-by-mspec-exe-but-passes-when-run-by-td-net">this问题了解为何测试运行失败了答案。

See this question for the answer why the test run fails.

这篇关于如何编写规范与MSpec为code,改变Thread.CurrentPrincipal中?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆