0

I want to unit test a my action method in my ASP.NET Core MVC controller, but I get this error, please help.

Message: Castle.DynamicProxy.InvalidProxyConstructorArgumentsException : Can not instantiate proxy of class: POSModels.CryptoParamsProtector. Could not find a parameterless constructor.

Stack Trace:
ProxyGenerator.CreateClassProxyInstance(Type proxyType, List1 proxyArguments, Type classToProxy, Object[] constructorArguments) ProxyGenerator.CreateClassProxy(Type classToProxy, Type[] additionalInterfacesToProxy, ProxyGenerationOptions options, Object[] constructorArguments, IInterceptor[] interceptors) CastleProxyFactory.CreateProxy(Type mockType, IInterceptor interceptor, Type[] interfaces, Object[] arguments) line 62 Mock1.InitializeInstance() line 311
Mock1.OnGetObject() line 325 Mock.get_Object() line 179 Mock1.get_Object() line 283
UnitTypesControllerTests.initController(Object obj) line 80
UnitTypesControllerTests.IndexTest() line 86

This is my unit test code and error is thrown from the last line in initController method.

namespace PWEB.Controllers.Tests
{
    using Xunit;

    public class UnitTypesControllerTests
    {
        private Mock<IHttpContextAccessor> contextAccessor;
        private UnitTypesController unitTypesController;
        private Mock<NetCorePOSSystemConfig> config;
        private Mock<IHttpClientFactory> httpClientFactory;
        private Mock<Microsoft.Extensions.Options.IOptions<NetCorePOSSystemConfig>> configure;
        private Mock<Microsoft.AspNetCore.Http.HttpContext> mockHttpContext;
        private Mock<MockHttpMessageHandler> mock;
        private Mock<CryptoParamsProtector> cryptoParams;
        PaginationEntity<UnitTypeModel> paginationEntity = new PaginationEntity<UnitTypeModel>()
        {
            Items = new List<UnitTypeModel>(),
            MetaData = new PaginationMetaData()
            {
                Count = 1,
                TotalItemCount = 1,
                PageNumber = 1,
                FirstItemOnPage = 1,
                HasNextPage = false,
                HasPreviousPage = false,
                IsFirstPage = true,
                IsLastPage = false,
                LastItemOnPage = 1,
                PageCount = 1,
                PageSize = 20
            }
        };

        public UnitTypesControllerTests()
        {
            cryptoParams = new Mock<CryptoParamsProtector>(MockBehavior.Strict);
            mock = new Mock<MockHttpMessageHandler>(MockBehavior.Strict);
        }

        private void initController(object obj)
        {
            string value = "1";
            byte[] val = new byte[] { 1 };             
            mock.Protected().Setup<Task<HttpResponseMessage>>("SendAsync", ItExpr.IsAny<HttpRequestMessage>(), ItExpr.IsAny<CancellationToken>()).ReturnsAsync(new HttpResponseMessage()
            {
                Content = new StringContent(Newtonsoft.Json.JsonConvert.SerializeObject(obj), System.Text.Encoding.UTF8, "application/json"),
                StatusCode = System.Net.HttpStatusCode.OK
            }).Verifiable();
            var client = new HttpClient(mock.Object)
            {
                BaseAddress = new Uri("http://xxxxxxxxxxxxxx")
            };

            httpClientFactory = new Moq.Mock<IHttpClientFactory>();
            httpClientFactory.Setup(x => x.CreateClient(It.IsAny<string>())).Returns(client);

            config = new Mock<NetCorePOSSystemConfig>();
            contextAccessor = new Mock<IHttpContextAccessor>();
            mockHttpContext = new Mock<Microsoft.AspNetCore.Http.HttpContext>();

            Mock<ISession> mocks = new Mock<ISession>();
            mocks.Setup(c => c.Set("JWToken", It.IsAny<byte[]>())).Callback<string, byte[]>((k, v) => value = v.ToString());
            mocks.Setup(v => v.TryGetValue("JWToken", out val)).Returns(true);
            mockHttpContext.Setup(v => v.Session).Returns(mocks.Object);
            contextAccessor.Setup(x => x.HttpContext).Returns(mockHttpContext.Object);
            configure = new Mock<Microsoft.Extensions.Options.IOptions<NetCorePOSSystemConfig>>();
            unitTypesController = new UnitTypesController(cryptoParams.Object, httpClientFactory.Object, configure.Object, contextAccessor.Object);
        }

        [Fact()]
        public void IndexTest()
        { 
                initController(paginationEntity);
                ViewResult result = unitTypesController.Index(1).Result as ViewResult;
                mock.Verify();
                Assert.IsType<StaticPagedList<UnitTypeModel>>(result.ViewData.Model);
            
        }
}

My controller is look like this,

public class UnitTypesController : Controller
    {
        private readonly HttpClient _httpClient;
        private readonly IOptions<NetCorePOSSystemConfig> _options; 
        private readonly IHttpContextAccessor contextAccessor;
        private readonly CryptoParamsProtector cryptoParams;
       

        public UnitTypesController(CryptoParamsProtector paramsProtector, IHttpClientFactory httpClientFactory, IOptions<NetCorePOSSystemConfig> config, IHttpContextAccessor httpContext)
        {
           //code          
             ..................
        }
}

encryption class look like this,

public class CryptoParamsProtector
    {
            IDataProtector _protector;

            public CryptoParamsProtector(IDataProtectionProvider dataProtectionProvider)
            {
                _protector = dataProtectionProvider.CreateProtector(GetType().FullName);
            }

            // ...........
    }
1
  • The issue is clear from the exception message. You do not have a parameterless constructor for the instantiation of the class. You ONLY have a constructor with a parameter set. Create one, that doesn't have any, and implement a check on your code that _protector is initialized. Or instatiate one manually. Or pass a parameter into your instantiation of the object it is trying to create an instance of. Commented Feb 15, 2023 at 7:05

1 Answer 1

0

when mocked the parameters in the constructor of CryptoParamsProtector, then issue was fixed

        private Mock<IDataProtectionProvider> mockIDataProtectionProvider = new Mock<IDataProtectionProvider>(MockBehavior.Strict);
        private Mock<IDataProtector> mockDpro = new Mock<IDataProtector>();

        public UnitTypesControllerTests()
        {
            mockIDataProtectionProvider.Setup(v=>v.CreateProtector(It.IsAny<string>())).Returns(mockDpro.Object);
            cryptoParams = new Mock<CryptoParamsProtector>(MockBehavior.Strict, mockIDataProtectionProvider.Object);
            mock = new Mock<MockHttpMessageHandler>(MockBehavior.Strict);
        }
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.