Unit test a singleton class with MSTest - c#

I want to test my class EventTextsDB that is a singleton, using MSTest in .NET 6.
I first thought about using AppDomain, but they basically were removed in .NET 5+ (https://learn.microsoft.com/en-us/dotnet/core/porting/net-framework-tech-unavailable#application-domains)
Then I found Unit test singletons, but by calling the private constructor via reflection I still cannot test the static Create() and static Delete() methods in the class, because they set the static EventTextsDB Instance property.
I could use ordered unit tests, but this would require a lot of work because I would have to order all tests that used this class. Not many tests use or test this class yet, but many do with a similar class LanguageDB, at which I want to apply the same solution that I am looking for.
I have read somewhere on stackoverflow or MSDN, that each test assembly runs isolated (in different AppDomain, if they still exist?), but I don't want to create 10 new test assemblies just for 10 tests of this class.
How can I test my singleton class?

Related

Unit testing QueueRuntimeInfo

I'm trying to write unit tests around Microsoft.Azure.ServiceBus and need to return a mock instance of Microsoft.Azure.ServiceBus.Management.QueueRuntimeInfo in my tests. QueueRuntimeInfo has an internal constructor which takes a string as a parameter. So any attempt with Moq or in code to instantiate gets QueueRuntimeInfo does not contain a constructor that takes 0 arguments. Cannot access internal constructor of QueueRuntimeInfo here.
Read numerous articles including: http://www.blackwasp.co.uk/MoqInternals.aspx and http://www.blackwasp.co.uk/CSharpFriendAssembly.aspx
But not sure if this the correct way to go and being honest not 100% sure of how to put/reference InternalsVisibleTo in my unit test which is in a .net core 2.2 solution.
Is it possible to be able to create an instance of this in my unit tests please?

How to unit test methods dependent on static methods in C#?

A method in the service which I'm unit testing is calling a static method that is present in another service.
I'm new to unit testing and have no idea how to mock these kinda dependencies. Please suggest!
There is already a thread here about this topic.
In fact it is not possible to create a service facade (Mock) for static methods.
My suggestion here is to refactor your code in that way that you make your class non static and create an interface for it. Than you can inject your dependency class in the normal system via IOC and in the unit test you can create a mock with frameworks like Moq or Rhinomocks.

How to execute XUnit tests via code

I have tests written in XUnit using InlineData and MemberData attributes. I would like to run tests via code elsewhere in my project and have the attributes automatically fill in test data like they normally do when ran through the VS test runner.
If it weren't for the attributes I would just call the methods directly like any other normal method. The asserts are still checked and it functions fine. But if I call a method directly that has the attributes, the attributes are ignored and I must provide all the test data manually through code. Is there some sort of test runner class in XUnit that I can reuse to accomplish this? I've been trying to dig through their API to no avail.
Why I want to do this will take some explanation, but bear with me. I'm writing tests against specific interfaces rather than their concrete implementations (think standard collection interfaces for example). There's plenty there to test and I don't want to copy paste them for each concrete implementer (could be dozens). I write the tests once and then pass each concrete implementation of the interface as the first argument to the test, a subject to test on.
But this leaves a problem. XUnit sees the test and wants to run it, but it can't because there are no concrete implementations available at this layer, there's only the interface. So I want to write tests at the higher layer that just new up the concrete implementations, and then invoke the interface tests passing in the new subjects. I can easily do this for tests that only accept 1 argument, the subject, but for tests where I'm using InlineData or MemberData too I would like to reuse those test cases already provided and just add the subject as the first argument.
Available for reference is the GitHub issue How to programmatically run XUnit tests from the xUnit.net project.
The class AssemblyRunner is now part of Xunit.Runner.Utility.
From the linked issue, xUnit.net contributor Brad Wilson provided a sample runner in the samples.xunit project on GitHub. This program demonstrates the techniques described in the issue. Namely, the portion responsible for running the tests after they have been discovered is as follows:
using (var runner = AssemblyRunner.WithAppDomain(testAssembly))
{
runner.OnDiscoveryComplete = OnDiscoveryComplete;
runner.OnExecutionComplete = OnExecutionComplete;
runner.OnTestFailed = OnTestFailed;
runner.OnTestSkipped = OnTestSkipped;
Console.WriteLine("Discovering...");
runner.Start(typeName);
finished.WaitOne(); // A ManualResetEvent
finished.Dispose();
return result;
}
For a deeper dive, he describes a method using XunitFrontController and TestDiscoveryVisitor to find and run tests. This is what AssemblyRunner does for its implementation.
Nevermind, I figured it out. Taking a closer look at XUnit's attribute hierarchy I found that the DataAttributes (InlineData, MemberData, etc) have a GetData method you can call to retrieve the set of data they represent. With a little reflection I can easily find all the tests in my test class and call the test methods, invoking the data attribute's get data method if there are any present, and perform the tests via my own code that way. The GetData part would have been much harder if I had to role my own version of it. Thank you XUnit authors for not forcing me to do that.

Visual Studio Test Project Start Up Event?

My projects all use StructureMap as a container/IoC. I leverage this in things like repository patterns. In my unit test project, I've implemented test repositories when it makes sense. In order for structure map to know what concrete implementation to use, I need to initialize the container and run registration of types. I'm looking for a place to call my IoC.Initialize() in a unit test project. Outside of unit test, for example, in a web project, I can initialize my IoC container/registration from the Global.asax. I'm looking for a Unit Test equivalent of a Global.asax (e.g. static void main, a way to wire into the main start up event entry point of Unit tests). I've got around this by using a base class for all my tests, and initializing in there, so any test that is run ends up initializing the IoC container if it's not already initialize... but it's very hack-ish IMHO, so I'm looking for a cleaner way.
Any suggestions?
UPDATE/ANSWER
The following is the solution I implemented per Matthew's response.
<TestClass()>
Public Module Main
Public Property TestContext As TestContext
<AssemblyInitialize()>
Public Sub Initialize(_TestContext As TestContext)
TestContext = _TestContext
IoC.Initialize()
End Sub
End Module
You're probably looking for the AssemblyInitializeAttribute. You can decorate a method with this in a class in your assembly and it will be run once before any tests in that assembly get run.

Unit testing private functions in Silverlight

Does anyone know how to test private functions in a Silverlight Unit Test project? The *_Accessor objects don’t seem to be available that are their in a normal unit testing project.
You cannot unit-test private functions. You have 3 options:
You can make those functions 'public' and test them,
You make them 'internal' and add the InternalsVisibleTo attribute in the assembly file.
You create a public or internal method that calls your private methods, and test those.
Unit testing is usually done to test the interface of classes to the outside world. Unit testing private methods is not recommended.
The answer by #sbenderli is correct.
But, I have my reservations about making private methods internal just to unit test them. Making a method internal is like making it public for that assembly.
Instead a better way would be to make the method protected and create a dummy class in your test assembly by inheriting from the class under test and then creating a public method which calls the protected method. Now you test the public method of the fake class.
If you have a genuine need to test private methods, then your architecture is in some way broken.
The open source framework Impromptu-Interface is able to expose private members using the DLR. The unit test for this feature are passing on Silverlight.

Categories

Resources