Im not able to mock ServiceBusReceivedMessage and ServiceBusMessageActions - c#

we want to write unit-test for servicebus message trigger. we are using Azure.Messaging.ServiceBus nuget package
[FunctionName("serviebustrigger")]
public async Task Run ([ServiceBusTrigger("xxxxtopic", "xxxxsubscription", Connection = "Abs-Connection", AutoCompleteMessages = false)] ServiceBusReceivedMessage message, ServiceBusMessageActions messageActions)
{
_logger.LogInformation($"{nameof(Run)} execution started for MessageId:{{MessageId}}", message.MessageId);
try
{
//some code
await messageActions.CompleteMessageAsync(message);
}
catch (Exception ex)
{
await messageActions.DeadLetterMessageAsync(message);
}
}
Now I want to write unit test for the above code. But I'm not able mock ServiceBusReceivedMessage and ServiceBusMessageActions as these have Internal Constructor. Can someone suggest me better way to write unit test

There was an oversight with the implementation of ServiceBusMessageActions where the mocking constructor was initially missed. This was corrected in v5.2.0 of the extensions package.
With that fix, a parameterless constructor is available to ensure that ServiceBusMessageActions is usable with a mocking framework such as Moq or FakeItEasy. Each of the public members are virtual or settable and the class is not sealed. You should be able to mock using the same approach that you prefer for other types - whether with a mocking framework or inheriting from the class and creating your own mock type - and make use of the model factory to simulate behavior.
For ServiceBusReceivedMessage and other model types that are returned by service operations, the ServiceBusModelFactory is used to create instances for testing purposes.

Related

Unit Testing and Mocking SubscriberClient (Google Pub/Sub) in a C# Project

I'm using Google Cloud Pub/Sub (Google.Cloud.PubSub.V1 (2.2.0)) in a .NET Core 3.1 project.
I'm trying to write a unit test for the code that retrieves messages from a Google Pub/Sub subscription.
My code is similar to what you find in the Google documentation.
var subscriber = await SubscriberClient.CreateAsync(subscriptionName);
try
{
var startTask = subscriber.StartAsync(async (PubsubMessage message, CancellationToken cancel) =>
{
//code
});
await Task.Delay(5000);
await subscriber.StopAsync(CancellationToken.None);
await startTask;
}
catch (Exception ex)
{
//code
}
Is there a way to mock SubscriberClient in a unit test? SubscriberClient doesn't appear to have an interface.
My unit tests are using NUnit (3.12.0) and Moq (4.14.5).
Any ideas would be appreciated.
Calling SubscriberClient.Create(...) instead of .CreateAsync(...) allows you to pass in the underlying SubscriberServiceApiClient instance(s).
Edit: Apologies, the above is incorrect, it should be:
Instantiate a SubscriberClientImpl directly instead of calling SubscriberClient.CreateAsync(...). This allows you to pass in the underlying SubscriberServiceApiClient instance(s).
Note that you can pass new SubscriberClient.Settings() for the settings argument, and null for the shutdown argument as defaults.
SubscriberServiceApiClient can be mocked - either directly, or by instantiated a SubscriberServiceApiClientImpl instance and passing in a mocked Subscriber.SubscriberClient.
When testing, note that SubscriberClient is multi-threaded and with default settings will call the callback passed to StartAsync concurrently from multiple threads.

Mocking Interface using Moq - never hits the mocked method

I am attempting to setup a simple unit test for my code. I have an interface and implementation that talks to an external service via WCF. I am attempting to mock this with the code below;
private Mock<IPayments> _mockIPayments;
_mockIPayments.Setup(x => x.GetCreditCard(It.IsAny<GetCreditCardRequest>())).Returns(getCreditCardResponse);
In the unit test itself, I create an instance of the service that would ultimately call the WCF service;
var paymentService = new PaymentService();
var response = paymentService.GetCardDetails(cardId);
Within the PaymentService itself, the code;
var response = ServiceInvoker.Invoke<IPayments, GetCreditCardRequest, GetCreditCardResponse>
(
"Payments",
request,
(proxy, req) => proxy.GetCreditCard(req));
(Note that ServiceInvoker.Invoke is just a wrapper to create a channel and process the request)
Am I missing something, should the mock setup not be catching the request to GetCreditCard?
ETA
To make it a little clearer, the flow is;
UnitTest -> PaymentsService -> IPayments
You need to pass your mocked instance to the service somehow.
var paymentService = new PaymentService(_mockIPayments.Object);
Simply specifying a setup will not let Moq replace all instances of some interface with the what you specified. It simply defines what Moq will return when a certain Mock instance will be called. In your case _mockIPayments.
You then have to use that mocked IPayments instance in your code (either pass it in a constructor or method) for your code to actually use it.
If your PaymentService is currently creating an IPayments object internally, to use mocking you will have to use something like Dependency Injection so that you are able to specify the IPayments instance externally and thus supply a mock instance in your tests.
Likewise:
var paymentService = new PaymentService(_mockIPayments.Object);

Unit testing Web Service responses

I am currently writing an API wrapper in C# for ResellerClub's REST/HTTP API, which provides responses in garden-variety JSON objects. Invocation is performed by performing HTTP POST/GET on API endpoints using the HttpClient class. JSON.Net is used for parsing the responses.
How I can unit test my API wrapper functionality for the API as most calls require a level of expected state in order to succeed. For example, I cannot test the creation of a CNAME record on a domain that I have not already registered.
I understand that tests should never rely on state which they do not arrange themselves, and I've also been told that the tests should never actually deal with any kind of persistence mechanism such as a database. So, for the above example of a CNAME record, that as part of the "Arrange" phase of the test I should register a test domain, assert it worked, then do the actual CNAME function?
Alternative, should I come up with some way of mocking the JSON responses that are returned from the Reseller Club API?
EDIT: Example of my API class (ResellerClubApi.cs)
private async Task<string> DownloadString(string uri)
{
// HttpClient object downloads the JSON response string asynchronously
}
The DownloadString() method is used by my functionality as a generic means of grabbing the response from the third party service.
public async Task<List<string>> SuggestNames(string domainName)
{
// Calls DownloadString() with the correct URI, uses Newtonsoft.JSON to parse
// string representation of JSON into object
}
Methods such as SuggestNames() above are called like this from the higher service layer
public void someServiceLayerMethod()
{
var rcApi = new ResellerClubApi();
var x = rcApi.SuggestNames("something");
// ...
}
As you can see, I am a bit stuck as to how to mock JSON responses from the likes of HttpClient when my ResellerClubApi class is the lowest possible layer of my own code prior to doing things over HTTP.
I also don't know how to start using IoC to hand the HttpClient dependency...
Thanks
I would separate the code from your ResellerClubApi class which involves downloading stuff and authorization, and everything that involves connecting to a remote service, in let's say a ResellerClubClient and have it implement a IResellerClubClient interface.
public interface IResellerClubClient {
string RequestJson(string url);
}
public class ResellerClubClient : IResellerClubClient {
// implement your methods here
}
public ResellerClubApi : IResellerClubApi {
private readonly IResellerClubClient client;
// Pass the client as dependency, either manually or using Dependency framework of your choice
public ResellerClubApi(IResellerClubClient client) {
this.client = client;
}
public List<string> SuggestNames(string domainName) {
var jsonString = this.client.RequestJson("http://example.com/domains/?name="+domainName);
// decode it and do something with it
}
}
This allows you to test your ResellerClubApi class without being depending on a concrete IResellerClubClient implementation. And the best is, you can change it (from HttpClient to socket or whatever and don't ever have to touch your ResellerClubApi.
And then set up your Unit test in framework of your choice. Some example with Moq framework:
var mockedJsonString = '{ succes: true, names: ["domainA.com", "domainA.us"] }';
// create mockup object using IResellerClubClient interface
var resellerClubClient = new Mock<IResellerClubClient>();
// Tell the mock object to return "mockedJsonString" when any parameter is passed to RequestJsonString.
// If you do more than 1 call in a test, or if that's expected to be called multiple times inside
// the method to be tested, you can setup multiple conditions and results this way too
resellerClubClient.Setup(x => x.RequestJson(It.IsAny<string>())).Returns(mockedJsonString);
var api = new ResellerClubApi(resellerClubClient.Object);
List<string> names = api.SuggestNames("domain.com");
// do your assertions here
By having abstracted the connection and data retrieving methods into hit's own class represented by an interface, you made your Api class UnitTestable and easy to mock server responses.
Of course, the ResellerClubClient can't be Unit tested of course. But it can be done in an integration test or a verification test. A UnitTest should never involve connecting to a server or a database.
Here is a way to do it by mocking the HttpMessageHandler using Moq unit test. http://geekswithblogs.net/abhi/archive/2013/11/20/unit-tests-for-httpclient-using-httpmessagehandler.aspx

Unit Testing Interface on Implementation

I have an interface which is used in an MVC controller which gets some data. To keep it simple the interface so far looks something like this:
public interface IDataProvider
{
DataModel GetData();
}
I have appropriate unit tests for this interface where it is called in the action. However, in the real implementation this will call a web service which of course could throw an exception, therefore if it does I want to write a test to ensure that I log a message if an error occurs.
To do this I have a logger interface which is actually an interface to NLog called ILogger. I could do this:
public interface IDataProvider
{
DataModel GetData(ILogger logger);
}
This would allow me to run unit tests for the logger making it nice and simple. However, I don't think this is the right way of doing this because the logger is really unrelated to this method. Also, if I start adding other methods to this interface which I need logging for then I will have to include the logger in the parameter of all of those methods as well.
The best way I can think of right now is to include the logger in the constructor of my implementation which might look like this:
public class DataProvider : IDataProvider
{
private readonly ILogger _logger;
public DataProvider(ILogger logger)
{
_logger = logger;
}
public DataModel GetData()
{
// CODE GOES HERE
}
}
However this means that I cannot test the logger in my unit tests. What is the best way to achieve this so that I can keep the logger separate from the method and make it testable?
I'll appreciate any help, thanks.
EDIT:
I realise I missed out unit testing code here is what I mean:
At the moment I am ensuring that GetData is called in my action this way:
var controller = new DataController(_dataProvider.Object);
controller.Index();
_dataProvider.Verify(dataProvider => dataProvider.GetData());
What I'd like to do is the same but for the logger but only if an exception is thrown like this:
_dataProvider.Setup(dataProvider => dataProvider.GetData()).Throws<WebException>();
var controller = new DataController(_dataProvider.Object);
controller.Index();
_logger.Verify(logger => logger.ErrorException(It.IsAny<string>(), It.IsAny<Exception>());
Obviously logger would be given to data provider in the setup. I hope that makes a bit more sense.
You can try using the factory pattern.
What happens here is in your production code, you are getting the logger from a Factory. In this factory, it returns either your real logger, or a fake logger which is setup in your unit tests. To your production code, it makes no difference what-so-ever.
In your Unit Tests, you are using a fake logger created using Moq. This fake allows you to test that an interface method was called, in this case ILogger.Log(). This is done by using the .Verify method.
Try something like this:
ILogger.cs
public interface ILogger
{
void Log(string message);
}
LoggerFactory.cs
public static class LoggerFactory
{
public static ILogger Logger
{
get
{
return LoggerFactory._logger == null ? new Logger() : LoggerFactory._logger;
}
set
{
LoggerFactory._logger = value;
}
}
private static ILogger _logger = null;
}
DataProvider.cs
public void GetData()
{
var logger = LoggerFactory.Logger;
logger.Log("..."); // etc...
}
UnitTest.cs
private void Mock<ILogger> _mockLogger = null;
public void Load()
{
this._mockLogger = new Mock<ILogger>();
LoggerFactory.Logger = _mockLogger.Object;
}
public void UnitTest()
{
// test as required
this._mockLogger.Verify(m => m.Log(It.IsAny<string>()));
}
Use a mocking framework (e.g. Moq or RhinoMocks) to verify that the logger was called. Then the final code block you post, where the logger is passed in via the constructor, will work.
Passing logger (or any other dependencies) in constructor is very standard practice and allows you to use dependency injection framework if needed.
I'm not sure why you see passing logger in constructor as limiting for unit test: you have 3 components that you can test separately
controller (depends on data provide, mock this dependency to test),
data provider (depends on logging and some other classes that let you call web service - mock all dependencies so you know when logging called and no need to call Web service)
logging - not sure what it depends on, but should be testable separately.
Notes:
use mocking framework (i.e. moq ) for your tests - you'll be able to provide any implementations of interfaces (including exceptions) very easily.
see if dependency injection framework (i.e. Unity ) would work for you. MVC4 is very well suited for it.
If you need to test that the logger is being called, I suggest using a test double called a "spy". This would not do any logging, but keep track of which methods (if any) were called. Then you can verify that the logger is called in specific instances.
You could do this by using a mocking framework to create the double (or mock) for you. Or you could create the ILogger implementation yourself. For example:
class LoggerSpy : ILogger
{
public string LogWasCalled;
public void Log(string message)
{
LogWasCalled = true;;
}
}
The following seems to have an example of mocking an ILogger using Moq: How to Mock ILogger / ILoggerService using Moq

Best approach for breaking dependencies in C#?

We are looking at adding unit tests to our C# code base. I am finding it easy to add unit tests to simple classes, but classes that interact with other dependencies are more difficult. I have been looking at mocking frameworks, but was wondering about the best approach to write classes in the first place to break external dependencies, like file system, database and messaging system dependencies.
To give an example, a routine listens on a socket for a message in a certain format - say MessageA. This is decoded, some calculations are done, this is re-encoded into a different binary format and the resulting message then sent, MessageB.
My current testing approach is as follows. I extract an interface for all socket interactions, and create a mock interface. I set the interface in a singleton. Then run the class against hard coded inputs. The class under test will use the interface in the singleton to send/receive.
I do a similar thing to test database interactions.
This does not seem like the most flexible approach, how would you go about improving this to make it easier to test? If a mocking framework is the answer, how would I design the classes?
Example code :
[SetUp]
public void init()
{
// set message interface in singleton as mock interface
CommAdapter.Instance.MessageAdapter = new MockMessage();
// build reference message from hard coded test variables
initialiseMessageA();
// set input from mock message socket
((MockMessage) CommAdapter.Instance.MessageAdapter).MessageIn = m_messageA;
}
[Test]
public void test_listenMessage_validOutput()
{
// initialise test class
MessageSocket tS = new MessageSocket();
// read from socket
tS.listenMessage();
// extract mock interface from singleton
MockMessage mm = ((MockMessage) CommAdapter.Instance.MessageAdapter);
// assert sent message is in correct / correstpoinding format
Assert.AreEqual(1000001, mm.SentMessageB.TestField);
}
Instead of using Singletons to set your component implementations, use a Dependency Injection, and a DI library like Ninject. This is exactly the type of scenario they were designed for.
Not pushing you to Ninject specifically, but they have a good tutorial :) The concepts will transfer to other frameworks (like Unity).
https://github.com/ninject/ninject/wiki
With DI alone, the code will look something like this:
class Samurai {
private IWeapon _weapon;
public Samurai(IWeapon weapon) {
_weapon = weapon;
}
public void Attack(string target) {
_weapon.Hit(target);
}
}
class Shuriken : IWeapon {
public void Hit(string target) {
Console.WriteLine("Pierced {0}'s armor", target);
}
}
class Program {
public static void Main() {
Samurai warrior1 = new Samurai(new Shuriken());
Samurai warrior2 = new Samurai(new Sword());
warrior1.Attack("the evildoers");
warrior2.Attack("the evildoers");
}
}
This looks clean now, but wait until your dependencies have dependencies, or further :) You can use a DI library to solve that, though.
With a library to handle the wiring up for you, it will look something like:
class Program {
public static void Main() {
using(IKernel kernel = new StandardKernel(new WeaponsModule()))
{
var samurai = kernel.Get<Samurai>();
warrior1.Attack("the evildoers");
}
}
}
// Todo: Duplicate class definitions from above...
public class WarriorModule : NinjectModule {
public override void Load() {
Bind<IWeapon>().To<Sword>();
Bind<Samurai>().ToSelf().InSingletonScope();
}
}
With either of these approaches, plus a mock object framework like Moq, your unit tests look something like this:
[Test]
public void HitShouldBeCalledByAttack()
{
// Arrange all our data for testing
const string target = "the evildoers";
var mock = new Mock<IWeapon>();
mock.Setup(w => w.Hit(target))
.AtMostOnce();
IWeapon mockWeapon = mock.Object;
var warrior1 = new Samurai(mockWeapon);
// Act on our code under test
warrior1.Attack(target);
// Assert Hit was called
mock.Verify(w => w.Hit(target));
}
You'll notice you can just pass mock instances straight into the code under test, and you don't have to mess around with setting singletons. This will help you avoid problems like needing to set up the state multiple times, or in between calls. It means no hidden dependencies.
You'll also notice I didn't use the DI container in the tests. If your code is well factored, it will only be testing a single class (and as often as possible, only a single method), and you will only need to mock out the direct dependencies of that class.
In addition to a DI container (I'm using MS Unity 2.0 currently but there are many to choose from) you will need a good mocking framework, my preference is MOQ. A common pattern/process for breaking concrete dependencies is:
define the dependency via an interface; you may luck out and already have an interface, like IDbConnection or you may need to use Proxy to wrap a concrete type and define your own interface.
resolve the concrete implementation via your DI container
inject your mock implementations into your DI container at test setup time (inject real impls. at system startup)

Categories