1

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

“System.Runtime.Serialization.SerializationException:没有为成员解析类型”

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

同样,如果我将 CurrentPrincipal 设置为 null,错误就会消失,但测试再次失败,因为未设置凭据。我用谷歌搜索了这个,发现了一些关于确保自定义主体在跨越 AppDomain 边界时可序列化的帖子(通常参考网络应用程序)。在我们的例子中,这不是一个网络应用程序,我没有跨越任何 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 设置为我们自定义主体的实例,其中已填充主体将完全访问权限。

这是一个足以导致错误的假 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 是一个企业库对象,它尝试访问配置。

4

1 回答 1

1

有关测试运行失败的答案,请参阅此问题。

于 2010-04-03T21:51:17.667 回答