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

本文关键字:字符串 XML 创建 FormsAuthenticationTicket 实例 有效 UserData | 更新日期: 2023-09-27 18:01:58

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

var testTicket = fixture.Create<FormsAuthenticationTicket>();
问题是UserData只能在使用以下构造函数实例化对象时设置:
public FormsAuthenticationTicket(int version, string name, DateTime issueDate, DateTime expiration, bool isPersistent, string userData);

其中"userData"是一个有效的XML字符串。

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

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

我认为一个可能的方法是自定义字符串生成算法…但是我没有参数知道何时提供XML,如字符串。

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

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

  1. 更改单个类型(FormsAuthenticationTicket)的构造器策略。
  2. userData构造函数参数提供自定义值。

以下自定义封装了两者:

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

希望对你有帮助。


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 @>

冻结字符串可以工作,但不希望这样做,因为它也会影响所有其他生成的字符串。

我使用这个类来定制一个特定的构造函数参数:

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>