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);
}
// ...........
}