Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How do you Mock a bad request using ProblemdetailsFactory #171

Open
developer9969 opened this issue Apr 25, 2022 · 3 comments
Open

How do you Mock a bad request using ProblemdetailsFactory #171

developer9969 opened this issue Apr 25, 2022 · 3 comments

Comments

@developer9969
Copy link

Hi
I would like to create a set of unit test using MOQ and would like to mock simple things like badRequest -NotFound etc...

I have tried a few things like below to set up the mock

`    public static void SetupMockProblemDetails(this Mock<ProblemDetailsFactory> mockProblemFactory)
    {
        mockProblemFactory
            .Setup(_ => _.CreateProblemDetails(
                It.IsAny<HttpContext>(),
                It.IsAny<int?>(),
                It.IsAny<string>(),
                It.IsAny<string>(),
                It.IsAny<string>(),
                It.IsAny<string>())
            )
            .Returns(new ProblemDetails())
            .Verifiable();
    }`

But I Crash when I map the mockProblemFactory.Object. How do you test BadRequest with your middleware?

 `  [Theory]
[InlineData("", "")]
public async Task GetCustomer_WithivalidId_BadRequest(string id)
{
    var mockRepo = new Mock<ICustomerRepository>();
    mockRepo.Setup(x => x.GetCustomer(It.IsAny<string>())).ReturnsAsync(() => new GetCustomerResponse { Customer = null }).Verifiable();

    var mockLogger = new Mock<ILogger<CustomerController>>();

    var mockProblemFactory = new Mock<Hellang.Middleware.ProblemDetails.ProblemDetailsFactory>();
    mockProblemFactory.SetupMockProblemDetails();
    var sut = new CustomerController(mockRepo.Object, mockLogger.Object);
    sut.ProblemDetailsFactory = mockProblemFactory.Object;

`

Thanks for any suggestions

@khellang
Copy link
Owner

Hi @developer9969! 👋🏻

But I Crash when I map the mockProblemFactory.Object

What's the crash? Any errors or details worth mentioning? I have little to go on here...

I would like to create a set of unit test

It would probably be much better to run in-memory integration tests for these scenarios.

@developer9969
Copy link
Author

developer9969 commented Apr 25, 2022

Hi @khellang
thanks you so much for your prompt reply.

It would probably be much better to run in-memory integration tests for these scenarios.

I was wondering that too, but because where I work all the other controller tests that do not use problemdetails (I introduced it) have unit tests with MOQ testing for badrequest- not result found etc.. I found myself struggling mocking problem details...

I

Castle.DynamicProxy.InvalidProxyConstructorArgumentsException
HResult=0x80070057
Message=Can not instantiate proxy of class: Hellang.Middleware.ProblemDetails.ProblemDetailsFactory.
Could not find a parameterless constructor.
Source=Castle.Core
StackTrace:
at Castle.DynamicProxy.ProxyGenerator.CreateClassProxyInstance(Type proxyType, List1 proxyArguments, Type classToProxy, Object[] constructorArguments) at Castle.DynamicProxy.ProxyGenerator.CreateClassProxy(Type classToProxy, Type[] additionalInterfacesToProxy, ProxyGenerationOptions options, Object[] constructorArguments, IInterceptor[] interceptors) at Moq.CastleProxyFactory.CreateProxy(Type mockType, IInterceptor interceptor, Type[] interfaces, Object[] arguments) at Moq.Mock1.InitializeInstance()
at Moq.Mock1.OnGetObject() at Moq.Mock.get_Object() at Moq.Mock1.get_Object()
etc...

I dont get the error when mocking using the microsoft problem details.. but still not sure if you can actually mock bad request etc... or I should just give up on those.? If is possible do you have a snippet?

@miryalarohith-10144
Copy link

I was facing error: Source=Castle.Core
StackTrace:
at Castle.DynamicProxy.ProxyGenerator.CreateClassProxyInstance(Type proxyType, List1 proxyArguments, Type classToProxy, Object[] constructorArguments) at Castle.DynamicProxy.ProxyGenerator.CreateClassProxy(Type classToProxy, Type[] additionalInterfacesToProxy, ProxyGenerationOptions options, Object[] constructorArguments, IInterceptor[] interceptors) at Moq.CastleProxyFactory.CreateProxy(Type mockType, IInterceptor interceptor, Type[] interfaces, Object[] arguments) at Moq.Mock1.InitializeInstance()
at Moq.Mock1.OnGetObject() at Moq.Mock.get_Object() at Moq.Mock1.get_Object()
at Microsoft.Crm.Extensibility.UnitTests.NonRelational.OrganizationInformationControllerTests.UnitTestBuilder..ctor(String requestUri, String apiName, Mock`1 handlerMock) in C:\CDS\src\Microsoft.Cds.UnitTests\Microsoft.Crm.Extensibility.UnitTests\NonRelational\OrganizationInformationControllerTests.cs:line this.Unit = mockOrganizationInformationController.Object;
at Microsoft.Crm.Extensibility.UnitTests.NonRelational.OrganizationInformationControllerTests.GetServiceEndPoint_ExecuteSucceed() in C:\CDS\src\Microsoft.Cds.UnitTests\Microsoft.Crm.Extensibility.UnitTests\NonRelational\OrganizationInformationControllerTests.cs:line UnitTestBuilder builder = new UnitTestBuilder(this.baseUri, "getserviceendpoint", handlerMock);
at System.RuntimeMethodHandle.InvokeMethod(Object target, Void** arguments, Signature sig, Boolean isConstructor)
at System.Reflection.MethodInvoker.Invoke(Object obj, IntPtr* args, BindingFlags invokeAttr)

		public UnitTestBuilder(string requestUri, string apiName, Mock<HttpMessageHandler> handlerMock)
		{
			requestUri += apiName;
			IOrganizationContext organizationContext = CreateMockIOrganizationContext();
			Mock<IExecutionContext> executionContext = new Mock<IExecutionContext>();
			Guid orgId = MetadataForMetadata.DummyOrgIdForMetadataForMetadataXmlLoader;
			executionContext = new Mock<IExecutionContext>();
			Mock<IExecutionContextFactory> executionContextFactory = new Mock<IExecutionContextFactory>();
			executionContextFactory.Setup(x => x.CreateInstance(It.IsAny<Guid>())).Returns(executionContext.Object);
			Mock<DynamicMetadataCache> mockCache = new Mock<DynamicMetadataCache>();
			Mock<IEntityDescription> entityDescription = new Mock<IEntityDescription>();
			entityDescription.Setup(x => x.LogicalName).Returns("testTable");
			entityDescription.Setup(x => x.ObjectTypeCode).Returns(1024);
			Mock<IEntityMetadataDataProvider> entityMetadataProvider = new Mock<IEntityMetadataDataProvider>();
			EntityMetadata entityMetadata = new EntityMetadata(entityDescription.Object, entityMetadataProvider.Object);
			mockCache.Setup(m => m.TryGetEntity(It.IsAny<int>())).Returns(entityMetadata);
			executionContext.SetupGet(x => x.MetadataCache).Returns(mockCache.Object);

			Mock<ILocatorService> locatorService = new Mock<ILocatorService>();

#pragma warning disable CS0618 // 'Do not use this test-only method that modifies static production state. Instead, enable unit test mocking by providing an interface-wrapped instance of the type you need to vary as a constructor parameter.'
LocatorService.TestSetInstance(locatorService.Object);
#pragma warning restore CS0618 // 'Do not use this test-only method that modifies static production state. Instead, enable unit test mocking by providing an interface-wrapped instance of the type you need to vary as a constructor parameter.'

			HttpClient httpClient = new HttpClient(handlerMock.Object);

			OrganizationSettingsClient organizationSettingsClient = new OrganizationSettingsClient(
				requestUri,
				httpClient);

#if NETFRAMEWORK
var configuration = new HttpConfiguration();
Mock mockResourceDiscovery = new Mock();
mockResourceDiscovery.Setup(x => x.GetGeoEndpointName(It.IsAny(), It.IsAny(), It.IsAny())).Returns("nrd.us-il002.gateway.test.island.powerapps.com");
this.Unit = new OrganizationInformationController(
executionContextFactory.Object,
organizationContext,
new OrganizationSettings(new Lazy(() => organizationSettingsClient), new Mock().Object, mockResourceDiscovery.Object))
{
Request = new HttpRequestMessage(HttpMethod.Get, requestUri)
};
this.Unit.Request.Properties[HttpPropertyKeys.HttpConfigurationKey] = configuration;
#else
var mockOrganizationInformationController = new Mock(
organizationContext,
new OrganizationSettings(new Lazy(() => organizationSettingsClient), new Mock().Object));

#pragma warning disable CS8632 // The annotation for nullable reference types should only be used in code within a '#nullable' annotations context.
mockOrganizationInformationController.Setup(oic => oic.Ok(It.IsAny<object?>()))
.Returns(new OkObjectResult(@"{""isAuditNoSqlReadEnabled"":true,""customEntityStorageDetails"":{""1024"":15678},""auditSize"":78}"));
#pragma warning restore CS8632 // The annotation for nullable reference types should only be used in code within a '#nullable' annotations context.

			var mockHttpContext = AspNetCoreTestHelper.CreateMockHttpContext(new Uri(requestUri), method: "GET");

			this.Unit = mockOrganizationInformationController.Object;

			this.Unit.ControllerContext = new ControllerContext()
			{
				HttpContext = mockHttpContext.Object
			};

#endif

			this.Unit.Request.Headers.Add("x-ms-correlation-id", Guid.NewGuid().ToString());
			this.Unit.Request.Headers.Add("Request-Id", Guid.NewGuid().ToString());
			this.Unit.Request.Headers.Add("Client-Session-Id", Guid.NewGuid().ToString());
			this.Unit.Request.Headers.Add("Client-Activity-Id", Guid.NewGuid().ToString());
			this.Unit.Request.Headers.Add("x-nls-debug", "true");
		}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants