What's an xUnit runsettings equivalent? - xunit

We have several environments that had their own run settings when we used MSTest. Since Microsoft is abandoning MSTest we are switching to xUnit. Whether it's through a runsettings or a command line property, I need a way to specify TestRunParameters in my xUnit test. Does xUnit have a native way to do that like MSTest or do I need to come up with my own solution?

While you can still use RunSettings to control some aspects of vstest.console while using xUnit the current version does not have a native way to pass in parameters. I believe v3 is going to have some kind of parameter passing.
For now you could use environment variables but if you are running multiple tests sets in parallel on the same system you would have conflicts.
I use a base class which reads in a TestSettings.json file with the settings for that test set. Using the following code I am able to pass in new types and have them read in by the base class json reader.
/// <inheritdoc />
/// <summary>
/// Common TestBase which uses CommonSettingsModel. Use TestBase<T> to override with custom settings Type.
/// </summary>
public abstract class TestBase : TestBase<CommonSettingsModel>
{
}
/// <inheritdoc />
/// <summary>
/// Common TestBase for loading settings.
/// </summary>
/// <typeparam name="T">Type to read TestSettings.json file</typeparam>
public abstract class TestBase<T> where T : ICommonSettings, new()
{
/// <inheritdoc />
/// <summary>
/// Constructor loads Settings T
/// </summary>
protected TestBase()
{
Settings = SettingsUtil.GetSettings<T>();
}
/// <summary>
/// Settings T loaded from TestSettings.json
/// </summary>
protected T Settings { get; }
}
You could also do the same type of thing with a Class or AssemblyFixture for the tests.
public class DatabaseFixture : IDisposable
{
public DatabaseFixture()
{
Db = new SqlConnection("MyConnectionString");
// ... initialize data in the test database ...
}
public void Dispose()
{
// ... clean up test data from the database ...
}
public SqlConnection Db { get; private set; }
}
public class MyDatabaseTests : IClassFixture<DatabaseFixture>
{
DatabaseFixture fixture;
public MyDatabaseTests(DatabaseFixture fixture)
{
this.fixture = fixture;
}
// ... write tests, using fixture.Db to get access to the SQL Server ...
}
https://xunit.net/docs/shared-context

Related

VC++ Intellisense inherited members

I have the following scenario in my code:
class A {
/// <summary>
/// returns the total number of frames that the consumer can accept
/// </summary>
/// <returns></returns>
virtual int GetRenderBufferSizeInFrames() = 0;
}
class B : public A {
int GetRenderBufferSizeInFrames();
}
void F() {
B BInstance;
BInstance.GetRenderBufferSizeInFrames(); // VC++ does not show the information about
// the method
}
When I hover the mouse over the function call, VC++ does not show me the info on the function. Is there a way to fix that? Logically it should be doing that, no?
No, you need to be explicit about that.
Try adding <inheritdoc/> to the derived method.
class B : public A {
/// <inheritdoc />
int GetRenderBufferSizeInFrames();
}
As a side note, I suggest to use an override specifier, to ensure you don't have a typo in the method name and make it visibly clear that this is overriding a virtual method from the base class.

SignalR MessagePack Polymorphism

I am implementing a system based on SignalR that will be pushing client events, for message serialization I would want to use MessagePack. When trying to implement the messaging I have run into a problem where SignalR fails to deserialize the messages on the client.
The messages are polymorphic and described with Union attributes, the standard MessagePack Serializer have no problem serializing and deserializing the messages BUT in case of Signal R it fails with error.
The error reported is System.InvalidOperationException: Invalid Union data was detected.
On the client serialization only works when using the actual class, if I try to use the interface or base class then the error appears.
Classes
[DataContract()]
[MessagePackObject()]
[Union(0,typeof(EntityChangeEventMessage))]
public abstract class EntityEventMessage : IEntityEventMessage
{
}
[DataContract()]
[MessagePackObject()]
public class EntityChangeEventMessage : EntityEventMessage
{
#region PROPERTIES
/// <summary>
/// Gets entity id.
/// </summary>
[DataMember(Order = 1)]
[Key(1)]
public int EntityId
{
get; set;
}
/// <summary>
/// Gets event type.
/// </summary>
/// <remarks>
/// This value identifies database operation such as create,delete,update etc.
/// </remarks>
[DataMember(Order = 2)]
[Key(2)]
public int EventType
{
get; set;
}
/// <summary>
/// Gets entity type name.
/// </summary>
[DataMember(Order = 3)]
[Key(3)]
public string EntityType
{
get; set;
}
#endregion
}
[Union(0,typeof(EntityChangeEventMessage))]
public interface IEntityEventMessage
{
}
So this works
connection.On("EntityEvent", (EntityChangeEventMessage d)
This dont work
connection.On("EntityEvent", (IEntityEventMessaged)
So in general it looks like the problem should be in the Microsoft.AspNetCore.SignalR.Protocols.MessagePack library ?
Anyone have implemented such functionality with success ?
Currently SignalR does not support polymorphism with MessagePack, more info here.

How to understand .netcore add scoped

I'm trying to understand the implementation or logic on how it works based on documentation. I am creating a .NET Core API
services.AddScoped<ICommanderRepo, SqlCommanderRepo>();
Documentation states that:
Adds a scoped service of the type specified in TService with an
implementation type specified in TImplementation to the specified
IServiceCollection.
public static IServiceCollection AddScoped<TService, TImplementation>(this IServiceCollection services)
where TService : class
where TImplementation : class, TService;
I want to know what is TService. And what is TImplementation. Because if i see it first time i dont know what it simply means.
SqlCommanderRepo implements ICommanderRepo interface.
public class SqlCommanderRepo : ICommanderRepo
{
private readonly CommanderContext _context;
public SqlCommanderRepo(CommanderContext context)
{
_context = context;
}
}
And CommanderContext extends DbContext
public class CommanderContext : DbContext
{
public CommanderContext(DbContextOptions<CommanderContext> opt) : base(opt)
{
}
}
What is TService. And what is TImplementation?
TService: The type of the service to add.
The contract for the service in your case is ICommanderRepo.
TImplementation : The type of the implementation to use.
The concrete type that implements the service in your case is SqlCommanderRepo.
From the source codes of ServiceCollectionServiceExtensions, AddScoped<TService, TImplementation> adds a scoped service of the type specified in TService with an implementation type specified in TImplementation to the specified IServiceCollection.
/// <summary>
/// Adds a scoped service of the type specified in <typeparamref name="TService"/> with an
/// implementation type specified in <typeparamref name="TImplementation"/> to the
/// specified <see cref="IServiceCollection"/>.
/// </summary>
/// <typeparam name="TService">The type of the service to add.</typeparam>
/// <typeparam name="TImplementation">The type of the implementation to use.</typeparam>
/// <param name="services">The <see cref="IServiceCollection"/> to add the service to.</param>
/// <returns>A reference to this instance after the operation has completed.</returns>
/// <seealso cref="ServiceLifetime.Scoped"/>
public static IServiceCollection AddScoped<TService, TImplementation>(this IServiceCollection services)
where TService : class
where TImplementation : class, TService
{
if (services == null)
{
throw new ArgumentNullException(nameof(services));
}
return services.AddScoped(typeof(TService), typeof(TImplementation));
}
/// <summary>
/// Adds a scoped service of the type specified in <paramref name="serviceType"/> to the
/// specified <see cref="IServiceCollection"/>.
/// </summary>
/// <param name="services">The <see cref="IServiceCollection"/> to add the service to.</param>
/// <param name="serviceType">The type of the service to register and the implementation to use.</param>
/// <returns>A reference to this instance after the operation has completed.</returns>
/// <seealso cref="ServiceLifetime.Scoped"/>
public static IServiceCollection AddScoped(
this IServiceCollection services,
Type serviceType)
{
if (services == null)
{
throw new ArgumentNullException(nameof(services));
}
if (serviceType == null)
{
throw new ArgumentNullException(nameof(serviceType));
}
return services.AddScoped(serviceType, serviceType);
}
Note:
Dependency injection in ASP.NET Core
Transient objects are always different; a new instance is provided to
every controller and every service.
Scoped objects are the same within a request, but different across
different requests.
Singleton objects are the same for every object and every request.

Generating documentation using TypeLite

Is it possible to configure TypeLite to replicate documentation from the source to the target class, so that tooltip docs are available in Visual Studio?
Here's a basic example (configured as described in TypeLite quickstart):
public class Poco
{
/// <summary>
/// Documentation.
/// </summary>
/// <remarks>
/// Remarks.
/// </remarks>
public string Name { get; set; }
}
Which generates the following:
interface Poco {
Name: string;
}
But I want:
interface Poco {
/**
* Documentation.
*
* Remarks.
*/
Name: string;
}
TypeLite supports generation of JDoc comments from Xml comments in C# classes. You need to call the WithJSDoc() fluent configuration method.
<#
var ts = TypeScript.Definitions()
.WithReference("Enums.ts")
.WithJSDoc();
#>
It requires XML files with documentation to be generated alongside your binaries.
This feature isn't supported in .NET portable projects.

Bootstrapper with Ninject using asp.net webapi

I am trying to use Bootstrapper to do initialization for my application, ioc, automapper, configuration etc.
I need some direction on how to setup the ninject correctly in asp.net webapi using bootstrapper. With the following configuration, my apicontroller is not able to resolve the IMyService dependency. Looks like it's using different ninject kernal.
My NinjectWebCommon
public static class NinjectWebCommon
{
private static readonly Bootstrapper bootstrapper = new Bootstrapper();
/// <summary>
/// Starts the application
/// </summary>
public static void Start()
{
DynamicModuleUtility.RegisterModule(typeof(OnePerRequestHttpModule));
DynamicModuleUtility.RegisterModule(typeof(NinjectHttpModule));
bootstrapper.Initialize(CreateKernel);
}
/// <summary>
/// Stops the application.
/// </summary>
public static void Stop()
{
bootstrapper.ShutDown();
}
/// <summary>
/// Creates the kernel that will manage your application.
/// </summary>
/// <returns>The created kernel.</returns>
private static IKernel CreateKernel()
{
var kernel = new StandardKernel();
kernel.Bind<Func<IKernel>>().ToMethod(ctx => () => new Bootstrapper().Kernel);
kernel.Bind<IHttpModule>().To<HttpApplicationInitializationHttpModule>();
GlobalConfiguration.Configuration.DependencyResolver = new MyResolver(kernel);
RegisterServices(kernel);
return kernel;
}
/// <summary>
/// Load your modules or register your services here!
/// </summary>
/// <param name="kernel">The kernel.</param>
private static void RegisterServices(IKernel kernel)
{
}
}
bootstrapper ninject registration
public class DIRegistration : INinjectRegistration
{
public void Register(IKernel container)
{
container.Bind<IMyService>().To<MyService>().InTransientScope();
}
}
public class MyService: IMyService
{
public string GetString()
{
return "My String!!!!!";
}
}
public interface IMyService
{
string GetString();
}
What i did to solve the problem is moving bootstrapper.Initialize(CreateKernel); to the IStartupTask implementation i have created for NinjectWebBootstrap. Basically use the IKernal injected by the Bootstrapper framework and run my registration and at the end set asp.net webapi and then set DepdendencyResolver with the custom resolve that takes in the injected IKernal instance.
DIRegistration is never used. So that binding does not exist.
I was trying to update the values directly in database but values were not updated in my WCF which uses entity framework using Ninject in svc file - the same way as in https://github.com/ninject/ninject.extensions.wcf/tree/master/src/Examples/WcfTimeService and using bootstraping.
If found out that if I recycle the IIS app pool, the data gets refreshed and it works as expected. I guess it IIS and Ninject which is creating this caching issue. Do you have any idea about it?

Resources