我一直在将一些旧规范转换为MSpec(使用NUnit / SpecUnit)。规范是针对视图模型的,并且所讨论的视图模型执行一些自定义安全检查。我们的规范中有一个帮助方法,它将为Thread.CurrentPrincipal设置虚假的安全凭证。这在旧的单元测试中运行良好,但在MSpec中失败了。具体来说,我得到了这个例外:
“System.Runtime.Serialization.SerializationException:未解析成员”
的类型
当部分SUT尝试读取应用配置文件时,会发生这种情况。如果我注释掉设置CurrentPrincipal的行(或者只是在检查配置文件的部分之后调用它),则错误消失,但由于缺少凭据而导致测试失败。
同样,如果我将CurrentPrincipal设置为null,则错误消失,但测试失败,因为未设置凭据。我已经google了这一点,并发现了一些关于确保自定义主体在跨越AppDomain边界(通常是参考Web应用程序)时可序列化的帖子。在我们的例子中,这不是一个Web应用程序,我没有跨越任何AppDomains。我们的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;
}
我们有许多这些“挑选者”视图模型,所有这些模型都表现出一些共同的行为。所以我正在使用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; }
}
这是ValidationFactory调用爆炸了。 ValidationFactory是一个企业库对象,它试图访问配置。