Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/20.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
.net 如何使用MSpec为更改Thread.CurrentPrincipal的代码编写规范?_.net_Multithreading_Security_Mspec - Fatal编程技术网

.net 如何使用MSpec为更改Thread.CurrentPrincipal的代码编写规范?

.net 如何使用MSpec为更改Thread.CurrentPrincipal的代码编写规范?,.net,multithreading,security,mspec,.net,Multithreading,Security,Mspec,我一直在将一些旧规范转换为MSpec(使用NUnit/SpecUnit)。这些规范是针对视图模型的,并且所讨论的视图模型执行一些自定义安全检查。在我们的规范中有一个helper方法,它将为Thread.CurrentPrincipal设置假安全凭据。这在旧的单元测试中运行良好,但在MSpec中失败。具体来说,我得到了一个例外: “System.Runtime.Serialization.SerializationException:未解析成员的类型” 当SUT的一部分尝试读取应用程序配置文件时,

我一直在将一些旧规范转换为MSpec(使用NUnit/SpecUnit)。这些规范是针对视图模型的,并且所讨论的视图模型执行一些自定义安全检查。在我们的规范中有一个helper方法,它将为Thread.CurrentPrincipal设置假安全凭据。这在旧的单元测试中运行良好,但在MSpec中失败。具体来说,我得到了一个例外:

“System.Runtime.Serialization.SerializationException:未解析成员的类型”

当SUT的一部分尝试读取应用程序配置文件时,就会发生这种情况。如果我注释掉设置CurrentPrincipal的行(或者在检查配置文件的部分之后调用它),错误就会消失,但是由于缺少凭据,测试失败

类似地,如果我将CurrentPrincipal设置为null,错误就会消失,但是测试再次失败,因为没有设置凭据。我在谷歌上搜索过这篇文章,发现了一些关于确保自定义主体在跨越AppDomain边界(通常指web应用)时可序列化的帖子。在我们的例子中,这不是一个web应用程序,我也没有跨越任何应用程序域。我们的pincipal对象也是可序列化的

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

那么,有人对我如何克服这个问题有什么想法吗?我真的很喜欢MSpec,并且很想专门使用它。但我需要能够在运行测试时提供假安全凭据

以下是规范类:

[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;
}
[主题(类型(CountryPickerViewModel))]
用户进行选择时的公共类:PickerViewModelSpecsBase
{
受保护的静态CountryPickerViewModel选择器;
建立上下文=()=>
{
SetupFakeSecurityCredentials();
CreateFactoryStubs();
StubLookupServicer()
.WithData(BuildActiveItems(新[]{“美国”、“英国”}));
picker=新的CountryPickerViewModel(ViewFactory、ViewModelFactory、,
BusinessLogicFactory、CacheFactory);
};
因为=()=>
picker.SelectedItem=picker.Items[0];
表现得像一个有选择的选择器;
}
我们有许多这样的“选取器”视图模型,它们都表现出一些常见的行为。所以我使用的是MSpec的行为特性。这个特定的类模拟用户从绑定到此VM的(WPF)控件中选择某些内容。 SetupFakeSecurityCredentials()方法只是将Thread.CurrentPrincipal设置为自定义主体的一个实例,在该实例中填充了prinipal将获得完全访问权限

下面是一个伪造的CountryPickerViewModel,它足以导致错误:

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; }

}
公共类CountryPickerViewModel
{
公共CountryPickerViewModel(IViewFactory viewFactory,
IViewModelFactory viewModelFactory,
ICoreBusinessLogicFactory业务逻辑工厂,
ICACHE工厂(工厂)
{
Items=新集合();
var validator=ValidationFactory.CreateValidator();
}
public int SelectedItem{get;set;}
公共集合项{get;private set;}
}

这是ValidationFactory的呼叫,它爆炸了。ValidationFactory是一个企业库对象,它尝试访问配置。

有关测试运行失败的原因,请参阅。

有关测试运行失败的原因,请参阅。

Dan,请发布示例代码,以便我们更容易调试您描述的行为?是的,测试在单独的AppDomain中运行,这样DLL的.config就可以由您的规范获取。再一次,在测试中设置Thread.CurrentPrincipal并从app.config读取值对我来说就像一股气味。这是应该驻留在单独类中的行为,这些类很容易在视图模型规范中存根。我同意你关于气味的两点。我们担心注入实际执行安全检查的代码,因为调用者可以很容易地做同样的事情(使用他们自己的实现),从而绕过我们的安全检查。另一方面,从理论上讲,他们也可以像我们在测试中一样在线程上伪造凭证。不确定什么是最好的方法。至于配置访问,这实际上是由企业库完成的。那完全是另一个话题Dan,你可以发布示例代码,让我们更容易调试你描述的行为吗?是的,测试在单独的AppDomain中运行,这样DLL的.config就可以由您的规范获取。再一次,在测试中设置Thread.CurrentPrincipal并从app.config读取值对我来说就像一股气味。这是应该驻留在单独类中的行为,这些类很容易在视图模型规范中存根。我同意你关于气味的两点。我们担心注入实际执行安全检查的代码,因为调用者可以很容易地做同样的事情(使用他们自己的实现),从而绕过我们的安全检查。另一方面,从理论上讲,他们也可以像我们在测试中一样在线程上伪造凭证。不确定什么是最好的方法。至于配置访问,这实际上是由企业库完成的。那完全是另一个话题