使用UserData中的有效XML字符串创建FormsAuthenticationTicket的实例

时间:2014-05-07 04:08:02

标签: c# .net autofixture

我想使用Autofixture创建FormsAuthenticationTicket的实例(我无法控制,部分是System.Web.Security)并确保UserData(类型为string)包含有效的XML字符串

var testTicket = fixture.Create<FormsAuthenticationTicket>();

问题是UserData只能在使用以下构造函数实例化对象时设置:

public FormsAuthenticationTicket(int version, string name, DateTime issueDate, DateTime expiration, bool isPersistent, string userData);

其中&#34; userData&#34;是一个有效的XML字符串。

我可以将此类型配置为使用最贪婪的构造函数,但这并不能解决向userData提供有效XML字符串的问题。

我可以冻结字符串类型以使其始终返回有效的XML字符串,但我也关心我的测试中的其他字符串值。

我在想一种可能的方法是自定义字符串生成算法......但是我没有参数来知道何时提供类似字符串的XML。

2 个答案:

答案 0 :(得分:2)

冻结字符串会起作用,但是不可取,因为它也会影响所有其他生成的字符串。

我使用此类来自定义特定的构造函数参数:

public class GenericArgCustomization<T> : ISpecimenBuilder
{
    private readonly string name;
    private readonly T value;

    public GenericArgCustomization(string name, T value)
    {
        if (String.IsNullOrEmpty(name))
            throw new ArgumentException("Name is required", "name");

        this.name = name;
        this.value = value;
    }

    public object Create(object request, ISpecimenContext context)
    {
        var pi = request as ParameterInfo;
        if (pi == null)
            return new NoSpecimen(request);

        if (pi.ParameterType != typeof(T) || pi.Name != this.name)
            return new NoSpecimen(request);

        return this.value;
    }
}

接下来,您可以通过指定泛型类型(在本例中为string)和要自定义的构造函数参数名称(在本例中为userData)来使用它。这是区分大小写的,因此它匹配您在类中使用的参数名称。

示例:

var xml = "<root>My Valid XML Value Here</root>";
var customUserData = new GenericArgCustomization<string>("userData", xml);
var fixture = new Fixture();
fixture.Customizations.Add(customUserData);
var item = fixture.Create<FormsAuthenticationTicket>();

现在使用以下数据创建项目:

  • 版本85
  • 姓名name1e8fb8b1-5879-4256-8729-ca6afeb1bd80
  • IssueDate 12/3/2015 8:00:05 AM
  • IsPersistent True
  • UserData <root>My Valid XML Value Here</root>

答案 1 :(得分:2)

AutoFixture选择适度的构造函数(默认情况下),因为userData不是适度的构造函数的一部分,我们需要在这里自定义两个的东西:

  1. 更改单个类型的构造函数策略(FormsAuthenticationTicket)。
  2. userData构造函数参数提供自定义值。
  3. 以下自定义包含两者:

    internal class UserDataCustomization : ICustomization
    {
        private readonly string userData;
    
        public UserDataCustomization(string userData)
        {
            this.userData = userData;
        }
    
        public void Customize(IFixture fixture)
        {
            fixture.Customize<FormsAuthenticationTicket>(c =>
                c.FromFactory(
                    new MethodInvoker(
                        new GreedyConstructorQuery())));
            fixture.Customizations.Add(new UserDataBuilder(this.userData));
        }
    
        private class UserDataBuilder : ISpecimenBuilder
        {
            private readonly string userData;
    
            public UserDataBuilder(string userData)
            {
                this.userData = userData;
            }
    
            public object Create(object request, ISpecimenContext context)
            {
                var pi = request as ParameterInfo;
                if (pi != null && pi.Name == "userData")
                    return this.userData;
    
                return new NoSpecimen();
            }
        }
    }
    

    以下测试通过:

    [Fact]
    public void UserDataIsCorrect()
    {
        var expected = "<foo></foo>";
        var fixture = new Fixture();
        fixture.Customize(new UserDataCustomization(expected));
    
        var actual = fixture.Create<FormsAuthenticationTicket>();
    
        Assert.Equal(expected, actual.UserData);
    }
    

    希望有所帮助。


    FWIW,F#中也是如此:

    open Ploeh.AutoFixture
    open Ploeh.AutoFixture.Kernel
    open System
    open System.Reflection
    open System.Web.Security
    
    type UserDataCustomization (userData) =
        let builder = {
            new ISpecimenBuilder with
                member this.Create(request, context) =
                    match request with
                    | :? ParameterInfo as pi 
                        when pi.Name = "userData" -> box userData
                    | _ -> NoSpecimen request |> box }
    
        interface ICustomization with
            member this.Customize fixture = 
                fixture.Customize<FormsAuthenticationTicket>(fun c ->
                    c.FromFactory(
                        MethodInvoker(
                            GreedyConstructorQuery())) :> ISpecimenBuilder)
                fixture.Customizations.Add builder
    

    以下测试通过:

    open Xunit
    open Swensen.Unquote.Assertions
    
    [<Fact>]
    let UserDataIsCorrect () =
        let expected = "<foo></foo>"
        let fixture = Fixture().Customize(UserDataCustomization(expected))
    
        let actual = fixture.Create<FormsAuthenticationTicket>()
    
        test <@ expected = actual.UserData @>