CallTracing 0.9.5

dotnet add package CallTracing --version 0.9.5
NuGet\Install-Package CallTracing -Version 0.9.5
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="CallTracing" Version="0.9.5" />
For projects that support PackageReference, copy this XML node into the project file to reference the package.
paket add CallTracing --version 0.9.5
#r "nuget: CallTracing, 0.9.5"
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
// Install CallTracing as a Cake Addin
#addin nuget:?package=CallTracing&version=0.9.5

// Install CallTracing as a Cake Tool
#tool nuget:?package=CallTracing&version=0.9.5

CallTracing

NuGet version (CallTracing)

Purpose

This library was developed with the aim to track mock calls in unit tests for .NET. Although other use cases could be discovered.

Motivation

Some mocking libraries have similar functionality. For example Moq library has MockSequence. But there was a desire to have this functionality without being dependent on the entire mocking library and its peculiarities of usage.

Example of usage

Let’s have the following interface and delegate. The interface defines a box which can be opened, closed, and things can be put into and counted. The purpose of the delegate is to write logs:

interface IBox
{
  int Count { get; }
  void Open();
  void PutInto(object thing);
  void Close();
}

delegate void WriteLog(string message);

And let's have the following method which should be tested:

static void FillBox(
  IBox box, 
  IEnumerable<object> things, 
  WriteLog writeLog)
{
    box.Open();
    writeLog("The box is opened.");

    foreach (var thing in things)
    {
        box.PutInto(thing);
    }

    writeLog($"The box has {box.Count} things.");

    box.Close();
    writeLog("The box is closed.");
}

The test should ensure that FillBox makes all necessary calls to IBox and WriteLog and does it in proper order.

Before writing the test let's create a mock for IBox first:

class BoxMock : IBox
{
  private readonly CallTrace callTrace;

  public BoxMock(CallTrace callTrace)
  {
      this.callTrace = callTrace;
  }

  public int Count
  {
      get
      {
          callTrace.Add((IBox box) => box.Count);
          return 2;
      }
  }

  public void Open()
  {
      callTrace.Add((IBox box) => box.Open());
  }

  public void PutInto(object thing)
  {
      callTrace.Add((IBox box) => box.PutInto(thing));
  }

  public void Close()
  {
      callTrace.Add((IBox box) => box.Close());
  }
}

Notice that BoxMock takes a CallTrace instance in the constructor and then uses it in its methods and properties to designate that the method or the property was called.

Then let's create a factory method for WriteLog delegate mock:

static WriteLog CreateWriteLogMock(CallTrace callTrace)
{
  return (string message) =>
  {
      callTrace.Add((WriteLog writeLog) => writeLog(message));
  };
}

Similarly to BoxMock the factory method takes a CallTrace instance and then it's used to designate that the delegate was called.

Now the test method to assert that right calls and in the right order were invoked can be implemented in following way:

static void Test()
{
  var callTraceActual = new CallTrace();
  
  var box = new BoxMock(callTraceActual);
  var writeLog = CreateWriteLogMock(callTraceActual);

  var things = new object[] { 1, 2 };
  FillBox(box, things, writeLog);

  var callTraceExpected = new CallTrace(
      (IBox box) => box.Open(),
      (WriteLog writeLog) => writeLog("The box is opened."),
      (IBox box) => box.PutInto(1),
      (IBox box) => box.PutInto(2),
      (IBox box) => box.Count,
      (WriteLog writeLog) => writeLog("The box has 2 things."),
      (IBox box) => box.Close(),
      (WriteLog writeLog) => writeLog("The box is closed."));

  Assert.Equal(callTraceExpected, callTraceActual);
}

Documentation

The example above demonstrates pretty much the entire functionality of the library.

Product Compatible and additional computed target framework versions.
.NET net6.0 is compatible.  net6.0-android was computed.  net6.0-ios was computed.  net6.0-maccatalyst was computed.  net6.0-macos was computed.  net6.0-tvos was computed.  net6.0-windows was computed.  net7.0 was computed.  net7.0-android was computed.  net7.0-ios was computed.  net7.0-maccatalyst was computed.  net7.0-macos was computed.  net7.0-tvos was computed.  net7.0-windows was computed.  net8.0 was computed.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.
  • net6.0

    • No dependencies.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last updated
0.9.5 390 5/18/2022
0.9.4 377 5/15/2022
0.9.3 364 5/15/2022
0.9.2 361 5/15/2022
0.9.1 368 5/12/2022
0.9.0 367 5/12/2022