Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/259.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 使用内部JSON构造函数和许多构造函数参数在AutoFixture 4.8.0中创建公共类型_C#_Autofixture - Fatal编程技术网

C# 使用内部JSON构造函数和许多构造函数参数在AutoFixture 4.8.0中创建公共类型

C# 使用内部JSON构造函数和许多构造函数参数在AutoFixture 4.8.0中创建公共类型,c#,autofixture,C#,Autofixture,与AutoFixture 4.8.0一样,除了使用Fixture.Register注册函数以创建仅公开内部构造函数的类型外,还有更好的替代方法吗 在这方面: 我正在开发一个.net标准类库来构建供内部使用的API。我们不想公开公共构造函数,因此这些模型的所有构造函数都是内部的。属性另外是公共只读的。这些类将通过JSON反序列化来实例化,并且在这个特定的库中有一个具有20个属性的模型要考虑。作为奖励,我们希望尽可能使用[AutoDataAttribute] 也就是说,除了使用AutoFixture

与AutoFixture 4.8.0一样,除了使用
Fixture.Register
注册函数以创建仅公开
内部
构造函数的类型外,还有更好的替代方法吗

在这方面: 我正在开发一个.net标准类库来构建供内部使用的API。我们不想公开公共构造函数,因此这些模型的所有构造函数都是
内部的
。属性另外是
公共只读的
。这些类将通过JSON反序列化来实例化,并且在这个特定的库中有一个具有20个属性的模型要考虑。作为奖励,我们希望尽可能使用[AutoDataAttribute]

也就是说,除了使用AutoFixture为内部jsonconstructor提供非复杂类型和复杂类型(也是内部类型)的混合,还有其他方法吗

[TestFixture]
public sealed class Tests
{
    private Fixture _fixture;

    [OneTimeSetUp]
    public void OneTimeSetup()
    {
        _fixture = new Fixture();

        _fixture.Register(() => new Vehicle(_fixture.Create<string>(), _fixture.Create<int>()));

        _fixture.Register(
            () => new Driver(_fixture.Create<string>(), _fixture.Create<int>(), _fixture.Create<Vehicle>()));
    }

    [Test]
    public void CanCreateDriverWithVehicle()
    {
        Func<Driver> func = () => _fixture.Create<Driver>();
        func.Should().NotThrow(); // Green
    }
}

[PublicAPI]
public sealed class Driver
{
    public readonly string Name;
    public readonly int Age;
    public Vehicle Vehicle;

    [JsonConstructor]
    internal Driver(string name, int age, Vehicle vehicle)
    {
        Name = name;
        Age = age;
        Vehicle = vehicle;
    }
}

[PublicAPI]
public sealed class Vehicle
{
    public readonly string Manufacturer;
    public readonly int Miles;

    [JsonConstructor]
    internal Vehicle(string manufacturer, int miles)
    {
        Manufacturer = manufacturer;
        Miles = miles;
    }
}
[TestFixture]
公开密封等级考试
{
私人固定装置(u Fixture);;
[一次性设置]
public void OneTimeSetup()
{
_夹具=新夹具();
_fixture.Register(()=>新车(_fixture.Create(),_fixture.Create());
_固定装置。登记册(
()=>新驱动程序(_fixture.Create(),_fixture.Create(),_fixture.Create());
}
[测试]
公共无效可创建带车辆的驾驶员()
{
Func Func=()=>_fixture.Create();
func.Should().NotThrow();//绿色
}
}
[公共空气污染指数]
公共密封级驱动程序
{
公共只读字符串名称;
公共只读信息时代;
公共车辆;
[JsonConstructor]
内部驱动程序(字符串名称、整数、车辆)
{
名称=名称;
年龄=年龄;
车辆=车辆;
}
}
[公共空气污染指数]
公共密封类车辆
{
公共只读字符串制造商;
公共只读整数英里数;
[JsonConstructor]
内部车辆(字符串制造商,整数英里)
{
制造商=制造商;
英里=英里;
}
}

默认情况下,AutoFixture仅考虑公共构造函数。它不会获取内部构造函数,即使它们可以从测试执行程序集访问(甚至不确定是否有合理的技术可能性来检查)

您可以轻松自定义夹具以支持该功能。从以下代码示例中获得灵感:

[Fact]
public void ShouldActivateTypesWithInternalConstructor()
{
    var fixture = new Fixture();

    fixture.ResidueCollectors.Add(
        new Postprocessor(
            new MethodInvoker(
                new ModestInternalConstructorQuery()),
            new AutoPropertiesCommand()
        ));

    var result = fixture.Create<TypeWithInternalConstructor>();

    Assert.NotEqual(0, result.Property);
}

public class ModestInternalConstructorQuery : IMethodQuery
{
    public IEnumerable<IMethod> SelectMethods(Type type)
    {
        if (type == null) throw new ArgumentNullException(nameof(type));

        return from ci in type.GetConstructors(BindingFlags.Instance | BindingFlags.NonPublic)
            where ci.IsAssembly // Take internal constructors only
            let parameters = ci.GetParameters()
            where parameters.All(p => p.ParameterType != type)
            orderby parameters.Length ascending
            select new ConstructorMethod(ci) as IMethod;
    }
}

public class TypeWithInternalConstructor
{
    public int Property { get; }

    internal TypeWithInternalConstructor(int property)
    {
        Property = property;
    }
}
[事实]
public void应使用InternalConstructor()激活etypes
{
var fixture=新fixture();
fixture.ResidueCollectors.Add(
新的后处理器(
新MethodInvoker(
新的ConstructorQuery()),
新的AutoPropertiesCommand()
));
var result=fixture.Create();
Assert.NotEqual(0,result.Property);
}
公共类构造函数查询:IMethodQuery
{
公共IEnumerable SelectMethods(类型)
{
如果(type==null)抛出新的ArgumentNullException(nameof(type));
从.GetConstructors类型中的ci返回(BindingFlags.Instance | BindingFlags.NonPublic)
其中ci.IsAssembly//仅接受内部构造函数
let parameters=ci.GetParameters()
其中parameters.All(p=>p.ParameterType!=type)
orderby参数。长度递增
选择新建ConstructorMethod(ci)作为i方法;
}
}
具有内部构造函数的公共类类型
{
公共int属性{get;}
内部类型WithInternalConstructor(int属性)
{
财产=财产;
}
}