Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/25.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# 使用Nsubstitute注册或配置IOC容器_C#_.net_Unit Testing_Dependency Injection_Nsubstitute - Fatal编程技术网

C# 使用Nsubstitute注册或配置IOC容器

C# 使用Nsubstitute注册或配置IOC容器,c#,.net,unit-testing,dependency-injection,nsubstitute,C#,.net,Unit Testing,Dependency Injection,Nsubstitute,我有一个定制的IOC容器,它接受接口和具体类型作为注册参数。在我的项目中,我已经注册了下面代码中提到的配置。你能帮我一个如何使用NSubstitute注册单元测试项目的人吗 IOC-Conatincer.cs Register<Intf, Impl>(); Register(); 应用程序-配置.cs Register<ICustomer,Customer>(); IOCContainer.Register(Substitute.For<IProvider&g

我有一个定制的IOC容器,它接受接口和具体类型作为注册参数。在我的项目中,我已经注册了下面代码中提到的配置。你能帮我一个如何使用NSubstitute注册单元测试项目的人吗

IOC-Conatincer.cs

Register<Intf, Impl>();
Register();
应用程序-配置.cs

Register<ICustomer,Customer>();
IOCContainer.Register(Substitute.For<IProvider>());
IOCContainer.Register(Substitute.For<ICustomer>());
Register();
单元测试应用程序-CustomerTest.cs

Register<ICustomer,StubCustomer>(); -I want something like this
var substitute = Substitute.For<ICustomer>(); but It provides something like this
Register()-我想要这样的东西
var substitute=substitute.For();但它提供了类似的东西

我不认为您可以通过Unity解决具体的实例,然后在其上提供替代属性/方法


由于您的目的是进行单元测试,因此需要使用NSubstitue解析实例,因为只有使用该实例,您才能配置属性/方法以返回对象或检查是否收到调用。

没有直接的方法使用like-Concrete类,作为一种解决方法,为Register()添加了一个重载方法,并作为参数传递

Container.cs

 public class IOCContainer
 {
    static Dictionary<Type, Func<object>> registrations = new Dictionary<Type, Func<object>>();
    public static void Register<TService, TImpl>() where TImpl : TService
    {
        registrations.Add(typeof(TService), () => Resolve(typeof(TImpl)));
    }
    public static void Register<TService>(TService instance)
    {
        registrations.Add(typeof(TService), () => instance);
    }
    public static TService Resolve<TService>()
    {
        return (TService)Resolve(typeof(TService));
    }
    private static object Resolve(Type serviceType)
    {
        Func<object> creator;
        if (registrations.TryGetValue(serviceType, out creator)) return creator();
        if (!serviceType.IsAbstract) return CreateInstance(serviceType);
        else throw new InvalidOperationException("No registration for " + serviceType);
    }
    private static object CreateInstance(Type implementationType)
    {
        var ctor = implementationType.GetConstructors().Single();
        var parameterTypes = ctor.GetParameters().Select(p => p.ParameterType).ToList();
        var dependencies = parameterTypes.Select(Resolve).ToArray();            
        return Activator.CreateInstance(implementationType, dependencies);
    }
}
公共类IOCContainer
{
静态字典注册=新字典();
公共静态无效寄存器(),其中TImpl:t服务
{
添加(typeof(TService),()=>Resolve(typeof(TImpl));
}
公共静态无效寄存器(TService实例)
{
Add(typeof(TService),()=>实例);
}
公共静态TService解析()
{
返回(TService)解析(typeof(TService));
}
私有静态对象解析(类型serviceType)
{
Func创建者;
if(registrations.TryGetValue(serviceType,out creator))返回creator();
如果(!serviceType.IsAbstract)返回CreateInstance(serviceType);
否则抛出新的InvalidOperationException(“没有注册”+serviceType);
}
私有静态对象CreateInstance(类型implementationType)
{
var-ctor=implementationType.GetConstructors().Single();
var parameterTypes=ctor.GetParameters().Select(p=>p.ParameterType.ToList();
var dependencies=parameterTypes.Select(Resolve).ToArray();
返回Activator.CreateInstance(implementationType,dependencies);
}
}
配置.cs

Register<ICustomer,Customer>();
IOCContainer.Register(Substitute.For<IProvider>());
IOCContainer.Register(Substitute.For<ICustomer>());
IOCContainer.Register(替换为());
IOCContainer.Register(替换为());

我给您的建议是使用一种工具来实现自动模拟容器模式,它是一种单元测试模式,可以作为问题的解决方案:“如何将单元测试与依赖项注入机制解耦?”

有关此模式的更多详细信息,请参阅本文:

我建议您使用的具体工具是AutoFixture,它更适合在中为您的测试创建假对象,但它还提供了自动模拟容器功能

以下是我在项目中如何与NSubstitute一起使用它:

所需库:NSubstitute、AutoFixture、AutoFixture.AutoNSubstitute

[TestClass]
公共类BuildingService测试
{
专用IFixture固定装置;
私有IBuildingRepository;
私人楼宇服务sut;
私有iBiildingServiceValidator验证程序;
[测试初始化]
public void TestInitialize()
{
fixture=新fixture().Customize(新的AutoNSubstituteCustomization());
repository=fixture.Freeze();
validator=fixture.Freeze();
sut=fixture.Create();
}
[测试方法]
公共异步任务CreateAsync_with invalidBuildings_ReturnsBadRequest()
{
//安排
var buildingForCreationDto=fixture.Create();
var validationResultWithErrors=CreateValidationResultWithErrors();
validator.Validate(Arg.Any())。返回(validationResultWithErrors);
//表演
var actual=await sut.CreateAsync(buildingForCreationTo);
//断言
实际.StatusCode.Should().Be(HttpStatusCode.BadRequest);
实际.Errors.Should().BeEquivalentTo(FailureDto.FromValidationFailures(validationResultWitherErrors.Errors));
}
}