How to Mock NserviceBus SendLocal using Moq - nservicebus

context.Verify throws exception: object reference not set to the instance of the object
var context = new Mock<IMessagehandlerContext>();
context.Setup(x => x.SendLocal(It.IsAny<object>()))
.Returns(Task.CompletedTask);
context.Verify(b => b.SendLocal(It.IsAny<objec>()), Times.Exactly(1))

Instead of mocking IMessageHandlerContext, I'd suggest you use TestableMessageHandlerContext from NServiceBus.Testing nuget package. Checkout the documentation here .
A sample of how to use it is as follows:
[Test]
public async Task ShouldReplyWithResponseMessage()
{
var handler = new MyReplyingHandler();
var context = new TestableMessageHandlerContext();
await handler.Handle(new MyRequest(), context)
.ConfigureAwait(false);
Assert.AreEqual(1, context.RepliedMessages.Length);
Assert.IsInstanceOf<MyResponse>(context.RepliedMessages[0].Message);
}

Related

OpenIddict Console Application - Get All Application Clients - ListSync Fails

I have written a simple console application to get all application clients from OpenIddict server. I tried all the possibilities and getting the syntax error. The code is below. I did not find any example in Github and found some outdated example (2017) is no longer relevant now. Please help
public static async Task<bool> Test()
{
var services = CreateServices();
var provider = services.BuildServiceProvider();
var scope = provider.CreateScope();
var context = scope.ServiceProvider.GetRequiredService<CustomDbContext>();
await context.Database.EnsureCreatedAsync();
var manager = scope.ServiceProvider.GetRequiredService<IOpenIddictApplicationManager>();
var result = await manager.FindByClientIdAsync("TestApp"); // It Works
IQueryable<OpenIddictEntityFrameworkCoreApplication> _applicationsQuery = Enumerable.Empty<OpenIddictEntityFrameworkCoreApplication>().AsQueryable();
_applicationsQuery.Where(apps => apps.ClientId != "");
var clients = manager.ListAsync<Func<OpenIddictEntityFrameworkCoreApplication>>(_applicationsQuery); //Compiler Error
return (result != null);
}
private static IServiceCollection CreateServices()
{
var services = new ServiceCollection();
services.AddDbContext<CustomDbContext>(opts =>
{
opts.UseSqlServer(
ConfigurationManager.ConnectionStrings["DefaultConnection"].ConnectionString,
b => b.MigrationsAssembly("Program"));
opts.UseOpenIddict();
});
services.AddOpenIddict() // Register the OpenIddict core components.
.AddCore(options =>
{
// Configure OpenIddict to use the Entity Framework Core stores and models.
// Note: call ReplaceDefaultEntities() to replace the default OpenIddict entities.
options.UseEntityFrameworkCore()
.UseDbContext<CustomDbContext>();
// Enable Quartz.NET integration.
options.UseQuartz();
});
return services;
}
ListAsync() returns an IAsyncEnumerable<T> collection, so you can use await foreach to iterate the collection:
await foreach (var application in manager.ListAsync())
{
Console.WriteLine(await manager.GetClientIdAsync(application));
}
You can also reference the System.Linq.Async package and use the async LINQ extensions. For instance, here's how you could retrieve all the client identifiers of all existing applications:
var identifiers = await manager.ListAsync()
.SelectAwait(application => manager.GetClientIdAsync(application))
.ToListAsync();

HttpClient not sending post data to NancyFX endpoint

I am doing some integration testing of my web API that uses NancyFX end points. I have the xUnit test create a test server for the integration test
private readonly TestServer _server;
private readonly HttpClient _client;
public EventsModule_Int_Tester()
{
//Server setup
_server = new TestServer(new WebHostBuilder()
.UseStartup<Startup>());
_server.AllowSynchronousIO = true;//Needs to be overriden in net core 3.1
_client = _server.CreateClient();
}
Inside a Test Method I tried the following
[Fact]
public async Task EventTest()
{
// Arrange
HttpResponseMessage expectedRespone = new HttpResponseMessage(System.Net.HttpStatusCode.OK);
var data = _server.Services.GetService(typeof(GenijalnoContext)) as GenijalnoContext;
//Get come random data from the DBcontext
Random r = new Random();
List<Resident> residents = data.Residents.ToList();
Resident random_residnet = residents[r.Next(residents.Count)];
List<Apartment> apartments = data.Apartments.ToList();
Apartment random_Apartment = apartments[r.Next(apartments.Count)];
EventModel model = new EventModel()
{
ResidentId = random_residnet.Id,
ApartmentNumber = random_Apartment.Id
};
//Doesnt work
IList<KeyValuePair<string, string>> nameValueCollection = new List<KeyValuePair<string, string>> {
{ new KeyValuePair<string, string>("ResidentId", model.ResidentId.ToString()) },
{ new KeyValuePair<string, string>("ApartmentNumber", model.ApartmentNumber.ToString())}
};
var result = await _client.PostAsync("/Events/ResidentEnter", new FormUrlEncodedContent(nameValueCollection));
//Also Doesnt work
string json = JsonConvert.SerializeObject(model, Formatting.Indented);
var httpContent = new StringContent(json, Encoding.UTF8, "application/json");
var response = await _client.PostAsync("/Events/ResidentEnter", httpContent);
//PostAsJsonAsync also doesnt work
// Assert
Assert.Equal(response.StatusCode, expectedRespone.StatusCode);
}
The NancyFX module does trigger the endpoint and receives the request but without the body
What am I doing wrong? Note that the NancyFX endpoint has no issue transforming a Postman call into a valid model.
The NancyFX endpoint
Alright I fixed it, for those curious the issue was that the NancyFX body reader sometimes does not properly start reading the request body. That is that the stream reading position isn't 0 (the start) all the time.
To fix this you need to create a CustomBoostrapper and then override the ApplicationStartup function so you can set up a before request pipeline that sets the body position at 0
Code below
protected override void ApplicationStartup(TinyIoCContainer container, IPipelines pipelines)
{
base.ApplicationStartup(container, pipelines);
pipelines.BeforeRequest.AddItemToStartOfPipeline(ctx =>
{
ctx.Request.Body.Position = 0;
return null;
});
}

Using JsonPatchDocument With PatchAsync In Blazor Client

In my Blazor Client project, I have the following code:
#using Microsoft.AspNetCore.JsonPatch
...
var doc = new JsonPatchDocument<Movie>()
.Replace(o => o.Title, "New Title");
await Http.PatchAsync("api/patch/" + MovieId, doc);
This won't compile with the following error:
Error CS1503 Argument 2: cannot convert from
'Microsoft.AspNetCore.JsonPatch.JsonPatchDocument'
to 'System.Net.Http.HttpContent'
After some research, I've installed Newtonsoft.Json but I'm unsure how to configure the project to use it, or if indeed this is the correct solution for getting JsonPatchDocument working in a Blazor Project?
If JsonPatchDocument is not supported by Blazor, how can I implement a HTTP Patch request?
I just had a different but related issue. You are correct that you need to be using Newtonsoft.Json instead of System.Text.Json on the client application. Here is an extension method that will turn your JsonPatchDocument into an HttpContent.
public static class HttpClientExtensions
{
public static async Task<HttpResponseMessage> PatchAsync<T>(this HttpClient client,
string requestUri,
JsonPatchDocument<T> patchDocument)
where T : class
{
var writer = new StringWriter();
var serializer = new JsonSerializer();
serializer.Serialize(writer, patchDocument);
var json = writer.ToString();
var content = new StringContent(json, Encoding.UTF8, "application/json-patch+json");
return await client.PatchAsync(requestUri, content);
}
I know it's late but I hope it's helpful.

How to test model binder in ASP.Net MVC 6?

I'm trying to write a unit test for a custom model binder in ASP.Net MVC 6. It seems simple enough. The model binder has a single BindModelAsync method which takes a ModelBindingContext parameter.
In my unit test, I'm trying to figure out how to fake the ModelBindingContext. At first, I thought I could use the default constructor and set the properties on the object that I need. This works for all of the properties except ModelType which is not settable.
I then looked at the static ModelBindingContext.CreateBindingContext but it takes a bunch of scary looking parameters. Looking at how some of the model binding tests within the MVC repo are written, it seems like it is not possible for me to mock the ModelBindingContext.ModelType (unless maybe I copy/paste those 6 classes from Microsoft.AspNetCore.Mvc.TestCommon).
Is there something simple/easy I am missing?
I've had some success in getting it working for some simple form and query string values. AspNetCore.Mvc v1.1.3
private static DefaultModelBindingContext GetBindingContext(IValueProvider valueProvider, Type modelType)
{
var metadataProvider = new EmptyModelMetadataProvider();
var bindingContext = new DefaultModelBindingContext
{
ModelMetadata = metadataProvider.GetMetadataForType(modelType),
ModelName = modelType.Name,
ModelState = new ModelStateDictionary(),
ValueProvider = valueProvider,
};
return bindingContext;
}
Using a query string provider
[TestMethod]
public async Task QueryStringValueProviderTest()
{
var binder = new MyModelBinder();
var queryCollection = new QueryCollection(
new Dictionary<string, StringValues>()
{
{ "param1", new StringValues("1") },
{ "param2", new StringValues("2") },
});
var vp = new QueryStringValueProvider(BindingSource.Query, queryCollection, CultureInfo.CurrentCulture);
var context = GetBindingContext(vp, typeof(MyModel));
await binder.BindModelAsync(context);
var resultModel = context.Result.Model as MyModel;
//TODO Asserts
}
Using a form collection provider
[TestMethod]
public async Task FormValueProviderTest()
{
var binder = new MyModelBinder();
var formCollection = new FormCollection(
new Dictionary<string, StringValues>()
{
{ "param1", new StringValues("1") },
{ "param2", new StringValues("2") }
});
var vp = new FormValueProvider(BindingSource.Form, formCollection, CultureInfo.CurrentCulture);
var context = GetBindingContext(vp, typeof(MyModel));
await binder.BindModelAsync(context);
var resultModel = context.Result.Model as MyModel;
//TODO asserts
}

Access Current NHibernate Session in Castle Windsor IOC Container

I am trying to access my current nhibernate session using IOC from within a running Quartz.net Job and every time it comes back as null stating the following:
'NHibernateSession.Current' threw an exception of type 'SharpArch.Domain.PreconditionException' NHibernate.ISession SharpArch.Domain.PreconditionException}. An ISessionStorage has not been configured
Here is my current code setup. I cannot figure out for the life of me how to setup my IOC so that the NHibernate ISession within my IScheduledMessageQueries query is set correctly. The Quartz triggers are working correctly, I just cannot access the ISession to call my queries from within the Job. Any help and/or advice?
Global.cs Code:
protected virtual void InitializeServiceLocator()
{
_container = new WindsorContainer(new XmlInterpreter()).Install(new WebWindsorInstaller());
StartQuartzScheduler();
ComponentRegistrar.AddComponentsTo(_container);
ServiceLocator.SetLocatorProvider(() => new WindsorServiceLocator(_container));
DependencyResolver.SetResolver(new WindsorDependencyResolver(_container));
var activator = new WebApiControllerFactory(_container);
GlobalConfiguration.Configuration.Services.Replace(typeof(IHttpControllerActivator), activator);
}
private static void StartQuartzScheduler()
{
ISchedulerFactory schedulerFactory = new StdSchedulerFactory();
IJobFactory jobFactory = new WindsorJobFactory(_container);
var scheduler = schedulerFactory.GetScheduler();
scheduler.JobFactory = jobFactory;
scheduler.Start();
var sendScheduledMessageJob = new JobDetailImpl("sendScheduledMessageJob", typeof(SendScheduledMessageJob));
var trigger = new CalendarIntervalTriggerImpl
{
StartTimeUtc = DateTime.UtcNow.Subtract(new TimeSpan(1)),
Name = "Daily Trigger",
RepeatIntervalUnit = IntervalUnit.Second,
RepeatInterval = 1
};
scheduler.ScheduleJob(sendScheduledMessageJob, trigger);
}
public class SendScheduledMessageJob : IJob
{
private readonly IScheduledMessageQueries _scheduledMessageQueries;
public SendScheduledMessageJob(IScheduledMessageQueries scheduledMessageQueries)
{
_scheduledMessageQueries = scheduledMessageQueries;
}
public void Execute(IJobExecutionContext context)
{
var unsentScheduledMessages =
_scheduledMessageQueries.GetAllUnsentScheduledMessages(DateTime.Now);
}
}