Reputation: 79
I want to emphasize that I am fairly new to creating Unit Test but I've been searching far and wide through google and documentation but I can't find a solution or alternative. So currently I am trying to create Unit test for a microservice my team mate and I are working on. The class constructor is structured as follows
public Constructor(IOptions<AMQ_Config> amqConfig, IConfiguration configuration)
{
this.amqConfig = amqConfig.Value;
this.amqConfig.UserName = configuration["AMQ:UserName"];
this.amqConfig.Password = configuration["AMQ:Password"];
//this.errorTypeConfig = errorTypeConfig.Value;
this.configuration = configuration;
AMQSubscriber();
}
When I create a new instance of the constructor in the Unit Test it will always call and iterate through the AMQSubscriber();
method. Naively I just made a duplicate constructor that excludes the method and adds another parameter:
public UnitTestConstructor(IOptions<AMQ_Config> amqConfig, IConfiguration configuration, IConnection connection)
{
this.amqConfig = amqConfig.Value;
this.amqConfig.UserName = configuration["AMQ:UserName"];
this.amqConfig.Password = configuration["AMQ:Password"];
//this.errorTypeConfig = errorTypeConfig.Value;
this.configuration = configuration;
this.connection = connection;
}
but this was done for unit testing purposes only. I've read around about how its not a good idea to do this because it defeats the purpose of Unit testing but I can't think how to isolate this since most of the methods require or depend on the parameters: IOptions<AMQ_Config> amqConfig, IConfiguration configuration
and our microservice is architectured for Apache NMS AMQ for sending, processing and receiving messages.
Upvotes: 0
Views: 815
Reputation: 10055
You have a few options:
AMQSubscriber()
to another interfaceSo you will have your constructor look like:
public Constructor(IOptions<AMQ_Config> amqConfig, IConfiguration configuration, IAMQSubscriber subscriber)
{
// Other code ...
subscriber.AMQSubscriber();
}
In your unit test, you could either mock IAMQSubscriber
using a mocking library, or you could provide a void implementation:
class VoidAMQSubscriberForUnitTest : IAMQSubscriber
{
public void AMQSubscriber()
{
// Do nothing.
}
}
For example:
// Real
new YourClass(... , new RealAMQSubscriber());
// Unit test
new YourClass(... , new VoidAMQSubscriberForUnitTest());
internal
constructor or static methods:In this case, only types in the same assembly and the unit test assembly could see those methods. i.e. stop test specific methods being seen publicly.
class YourClass
{
// Only consumed by unit test
internal YourClass(IOptions<AMQ_Config> amqConfig, IConfiguration configuration, IConnection connection)
{ }
// Only consumed by unit test
internal static YourClass CreateForUnitTest() { }
}
You might need to add InternalsVisibleToAttribute to your assembly.
Upvotes: 1