Home > Software engineering >  Mocking ASP Net Core GetService<T>
Mocking ASP Net Core GetService<T>

Time:03-01

Require help in mocking Dependency Injection GetService method in ASP NET Core 5, with MOQ - 4.16.1, Nunit 3

Here is my production code:

class SomeClass(){  
    IServiceProvider serviceProvider;
   
    public SomeClass(IServiceProvider serviceProvider){
        this.serviceProvider = serviceProvider; 
    }

    void MethodHello(UserType type) {
        var service =  serviceProvider.GetService<Func<UserType, UserTypeBase>>();
                
        Console.WriteLine(service(type).GetAge());
    }
}
    
public enum UserType {
    Male,
    Female
}

My Unit tests:

class SomeClassTest{

    Mock<UserTypeBase> mockMale = new();
    Mock<UserTypeBase> mockFemale = new();
    
    Mock<IServiceProvider> serviceProvider = new Mock<IServiceProvider>(MockBehavior.Loose);

    [SetUp] 
    public SetUp(){
    
        Func<UserType, UserTypeBase> func = (type) => {
            if (type == UserType.Male)
              return mockMale.Object;
            else return mockFemale.Object;
        };
        serviceProvider.Setup(x => x.GetService(typeof(Func<UserType, UserTypeBase>)))
                       .Returns(func);
        mockMale.SetUp(x => x.GetAge()).Returns(20);
        mockFemale .SetUp(x => x.GetAge()).Returns(50);
    }
    
    [Test]
    public void Test_MethodHello(){
       
        new SomeClass(serviceProvider.Object).MethodHello(UserType.Male);
    
    }
}

With this, MOQ framework throws exception: Object of type 'System.RuntimeType' cannot be converted to type UserType.

Things I have tried:

serviceProvider.Setup(x => x.GetService<Func<UserType, UserTypeBase>())
    .Returns(func);

serviceProvider.Setup(x => x.GetService(It.IsAny<Func<UserType, UserTypeBase>>))
    .Returns(func);

Nothing seem to work.

CodePudding user response:

Code smell aside, I would suggest using an actual IServiceProvider to avoid having to arrange the behavior

class SomeClassTest{

    Mock<UserTypeBase> mockMale = new();
    Mock<UserTypeBase> mockFemale = new();
    
    IServiceProvider serviceProvider;

    [SetUp] 
    public void SetUp(){
    
        mockMale.SetUp(x => x.GetAge()).Returns(20);
        mockFemale .SetUp(x => x.GetAge()).Returns(50);

        Func<UserType, UserTypeBase> func = (type) => {
            if (type == UserType.Male)
              return mockMale.Object;
            else return mockFemale.Object;
        };

        IServiceCollection services = new ServiceCollection();
        services.AddSingleton(func);

        serviceProvider = services.BuildServiceProvider();
        
    }
    
    [Test]
    public void Test_MethodHello(){
       
        new SomeClass(serviceProvider).MethodHello(UserType.Male);
    
    }
}
  • Related