CallTracing 0.9.4

There is a newer version of this package available.
See the version list below for details.
dotnet add package CallTracing --version 0.9.4
NuGet\Install-Package CallTracing -Version 0.9.4
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.4" />
For projects that support PackageReference, copy this XML node into the project file to reference the package.
paket add CallTracing --version 0.9.4
#r "nuget: CallTracing, 0.9.4"
#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.4

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

CallTracing

NuGet version (CallTracing)

Purpose

This library was developed with the aim to track mock calls within unit tests. Although other use cases also can 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 bodies to designate that a method or a property was called.

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

static WriteLog CreateWriteLog(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 a delegate was called.

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

void Test()
{
  var callTraceActual = new CallTrace();
  
  var boxMock = new BoxMock(callTraceActual);
  var writeLogMock = CreateWriteLog(callTraceActual);

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

  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