在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,如字符串。
AutoFixture选择适度构造函数(默认情况下),由于userData
不是适度构造函数的一部分,我们需要在这里自定义两个内容:
- 更改单个类型(FormsAuthenticationTicket)的构造器策略。
- 为
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>();
现在用如下数据创建项目:
- 版本:
- 名称:
name1e8fb8b1-5879-4256-8729-ca6afeb1bd80
- IssueDate:
12/3/2015 8:00:05 AM
- IsPersistent:
True
- UserData:
<root>My Valid XML Value Here</root>
85