使用静态惰性实例自动固定创建对象

问题描述 投票:0回答:1

我正在尝试测试一个服务类,遇到了一些困难

此类具有私有构造函数,因此有必要从返回Lazy _singleton值的静态Instance属性创建它。

public class MyService : IMyService
{
    private static readonly Lazy<IMyService> _singleton = new Lazy<IMyService>(() => new MyService(new InjectedService()));
    public static IPermissionService Instance = _singleton.Value;

    private readonly IInjectedService _injectedService;

    private MyService(IInjectedService injectedService) => _injectedService = injectedService;


    // instance method I want to test
    public void DoSomething()
    {

    }
}

我正在尝试使用Create()方法使用AutoFixture和AutoMoq创建我的对象,但它一直在抱怨我没有公共构造函数。如果我将此构造函数设置为public,我仍然会收到错误消息,该错误似乎来自Lazy函数。

有人可以帮忙吗?我可能遇到其他类型的设计问题。我不知道是否可以轻松解决。

编辑1:我没有任何IoC容器,因此可以将我的服务注册为单例。我试图使用此方法来模拟依赖项服务的注入,以便可以使用模拟编写测试。

我已经取得了一些进步,但是我不确定我也喜欢...无论如何我会分享我拥有的东西

public static class My
{
    private static readonly Lazy<IMyService> _singleton = new Lazy<IMyService>(() => new MyService(new InjectedService()));
    public static IPermissionService Service = _singleton.Value;
}

public class MyService : IMyService
{
    private readonly IInjectedService _injectedService;

    public MyService(IInjectedService injectedService) => _injectedService = injectedService;


    // instance method I want to test
    public void DoSomething()
    {

    }
}

通过这种方式,我可以使用AutoFixture构建我的类并冻结InjectionService的模拟。

而且我可以这样使用静态类

My.Service.DoSomething();

在我的测试中

Fixture.Freeze<Mock<IInjectedService>>().Setup(...);
var service = Fixture.Create<MyService>();

service.DoSomething();
// assert my things
c# autofixture automoq
1个回答
0
投票
并非完全推荐,它比使用自动模拟容器要少一些,但混蛋注入(特别是用于属性注入)应该可以到达那里。

根据访问需求,将静态属性标记为internal可能会或可能不会对将来的读者有所帮助,并且由于您很快做出更改,允许在单例模式之外创建实例类,因此您似乎可以很好。

如果为要注入的依赖项添加静态属性,则可以更改单例初始化程序以使用其值(如果有的话)。

public class MyService : IService { private static readonly Lazy<IService > _singleton = new Lazy<IService >(() => new MyService(MyDependency ?? new BastardizedInjectable())); public static IService Instance = _singleton.Value; internal static IMyDependency MyDependency { get; set; } private readonly IMyDependency _injectedService; private MyService(IMyDependency injectedService) => _injectedService = injectedService; // instance method I want to test public void DoSomething() { var stuff = _injectedService.GetStuff(); } }

通过此实现,您的测试应该能够执行以下操作:

fixture.Customize<MyService>(c => c.FromFactory(() => MyService.Instance)); var depMock = fixture.Freeze<Mock<IMyDependency>>(); MyService.MyDependency = depMock; var sut = fixture.Create<MyService>();

如上所述<?? new Bastard()。
© www.soinside.com 2019 - 2024. All rights reserved.