使用 IServiceProvider.GetRequiredService 对方法进行单元测试会抛出“未注册类型‘<T>’的服务”

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

我有一个类,它在构造函数中将

IServiceProvider
作为参数,并且在
Get()
方法中,它使用
IServiceProvider.GetRequiredService
返回一个对象。当对该方法进行单元测试以查看它是否返回预期类型的对象时,它会抛出
System.InvalidOperationException
异常并显示消息
No service for type '..MyType..' has been registered
。单元测试的方法应该是什么?

我对更改

Get()
方法或
Foo
类实现有限制。因此,这不是一个选项。

此外,无法模拟

IserviceProvider.GetRequiredService
,因为这是一个框架扩展方法。因此,没有使用过这种方法。

实施:

public class Foo
{
    private IServiceProvider _serviceProvider;

    public Foo(IServiceProvider serviceProvider, IOtherService s1, IOtherService2 s2){
       _serviceProvider = serviceProvider;
       //...mapping other dependencies here    
    }

    public IType Get (string type){
        switch (type){

        //This line throws the DI exception when unit test
        //No service for type 'MyType' has been registered
        //Cannot change this implementation

        case "a": return (IType)_serviceProvider.GetRequiredService(typeof(MyType));

        //other cases here 
        //......
        }
    }
}

使用

NUnit.Framework, Autofac.Extras.Moq, Moq

进行单元测试
[Test]
public void MyTest()
{
  using var am = AutoMock.GetLoose();
  var foo= am.Create<Foo>();

  //DI Exception when calling this method
  //No service for type 'MyType' has been registered
  foo.Get("a");
  
 //Assert here
 //....
}

非常感谢您对解决此问题的支持。

c# nunit .net-6.0 moq autofac
1个回答
0
投票

仅仅因为涉及到接口,并不意味着您必须将其替换为测试替身。在这种情况下,使用 ServiceCollection:

似乎更容易
[Test]
public void MyTest()
{
    var sc = new ServiceCollection();
    sc.AddSingleton<MyType>();
    var sp = sc.BuildServiceProvider();
    var sut = new Foo(sp, new Other(), new Other2());

    var actual = sut.Get("a");

    Assert.That(actual, Is.InstanceOf<MyType>());
}

本次测试通过。

© www.soinside.com 2019 - 2024. All rights reserved.