'Setting up IActionDescriptorCollectionProvider for a unit test

I am currently writing unit tests for a TagHelper that uses IActionDescriptorCollectionProvider in its constructor. My setupt looks as below so far - any ideas on how to set up something to satisfy IActionDescriptorCollectionProvider and allow me to change the value of IActionDescriptorCollectionProvider.ActionDescriptors.Items for my testing?

I can't use the DefaultActionDescriptorCollectionProvider implementation as it is inaccessible. Is there a simple way of doing this, or should I just substitute it with NSubstitute?

[SetUp]
public void Setup()
{
            
    IHttpContextAccessor contextAccessor = new HttpContextAccessor();
    contextAccessor.HttpContext = new DefaultHttpContext();
    contextAccessor.HttpContext.Request.Path = "/foo";
            
    IActionDescriptorCollectionProvider actionDescriptorCollectionProvider;
    actionDescriptorCollectionProvider = new DefaultActionDescriptorCollectionProvider();

    ActivePathSegmentTagHelper helper;
    helper = new ActivePathSegmentTagHelper(contextAccessor, actionDescriptorCollectionProvider);
    helper.Area = "";
    helper.Controller = "Home";
    helper.Action = "Index";  
}


Solution 1:[1]

As far as I know, if you want to use IActionDescriptorCollectionProvider in unit test, you could directly mock it and then use delegate with it.

More details, you could refer to below test demo source codes:

https://github.com/dotnet/aspnetcore/blob/c565386a3ed135560bc2e9017aa54a950b4e35dd/src/Mvc/Mvc.Core/test/Routing/ActionEndpointDataSourceBaseTest.cs

Solution 2:[2]

Its too late for u.. but for someone else heading this problem.. I just used this class

using Microsoft.AspNetCore.Mvc.Abstractions;
using Microsoft.AspNetCore.Mvc.Infrastructure;
using Moq;
using System.Collections.Generic;

public abstract class ActionDescriptorCollectionProviderMock
{
    public static readonly IActionDescriptorCollectionProvider ADCP = GetADCP();

    private static IActionDescriptorCollectionProvider GetADCP()
    {
        var actionDescriptorCollectionProviderMock = new Mock<IActionDescriptorCollectionProvider>();

        actionDescriptorCollectionProviderMock.Setup(m => m.ActionDescriptors).Returns(new ActionDescriptorCollection(new List<ActionDescriptor>(), 0));

        return actionDescriptorCollectionProviderMock.Object;
    }
}

and in test:

    [Fact]
    public async void GetByIdTest()
    {
        //Arrange
        var controller = new SomeController(ActionDescriptorCollectionProviderMock.ADCP);

        //Act
        ...

        //Assert
        ...        
    }

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Brando Zhang
Solution 2 Qhori