我正在尝试测试一个服务类,遇到了一些困难
此类具有私有构造函数,因此有必要从返回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
根据访问需求,将静态属性标记为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()。