SkillAgentSearch skills...

JazSharp

Jasmine inspired mocking and unit testing framework for C#.

Install / Use

/learn @Sellorio/JazSharp
About this skill

Quality Score

0/100

Supported Platforms

Universal

README

JazSharp

Contents

<a id="prereqs"></a>

Prerequisites

  • .NET Core 2.2 Runtime

<a id="intro"></a>

Introduction

JazSharp is heavily inspired by Jasmine - the JavaScript unit testing framework. Angular developers will be very familiar with it since that is the unit testing framework used in a CLI created default app.

Why was this made?

Originally, JazSharp was only aiming to be a mocking framework but after the initial implementation attempts proved to be unreliable, the scope increased to be a full unit testing framework.

The benefits of JazSharp over other mocking frameworks are:

  • No reliance on interfaces or similar layers of separation that are not motivated by clean development practises.
  • No issues when testing code that changes static/global values for the app - statics methods and properties can be mocked just like any method.
  • An alternative approach to defining mocks. This is less of a benefit and more of a personal preference. For example, parameters can be checked after a mock is called and defining a mock is quick and easy.

The syntax used to define test methods is also very different from other .Net testing frameworks and allows test names (or descriptions in the case of JazSharp) to read more clearly both to technical and non-technical persons.

<a id="userGuide"></a>

User Guide

<a id="installation"></a>

Installation

To start using JazSharp, all you have to do is install the JazSharp and JazSharp.TestAdapter nuget packages from nuget.org. The former is the core of the framework and the latter enables the framework to work with Visual Studio's Test Explorer as well as allowing tests to be executed by calling dotnet test.

<a id="creatingTests"></a>

Creating tests

<a id="testClass"></a>

Creating the test class

A test class in JazSharp is any class that inherits from JazSharp.Spec. The class does not need to be public. Unlike the common practise in JavaScript (when using Jasmine), it is recommended to place test classes in a dedicated unit test assembly (as is popular when unit testing in .Net).

An empty test class would look something like this:

class FooSpec : Spec
{
    public FooSpec()
    {
    }
}

<a id="describes"></a>

Describes (test scopes)

All tests need to be grouped into one or more levels of Describes. The first Describe should almost always be used to state which class is being tested.

class FooSpec : Spec
{
    public FooSpec()
    {
        Describe<Foo>(() =>
        {
        });
    }
}

Note: for static types, you will need to revert to specifying the name manually.

class StaticFooSpec : Spec
{
    public StaticFooSpec()
    {
        Describe(nameof(StaticFoo), () =>
        {
        });
    }
}

The next Describe will usually be used to specify the method being tested.

class FooSpec : Spec
{
    public FooSpec()
    {
        Describe<Foo>(() =>
        {
            Describe(nameof(Foo.Bar), () =>
            {
            });
        });
    }
}

At this point it is common to start specifying your tests but sometimes additional describes are used to group tests together by a particular scenario.

class FooSpec : Spec
{
    public FooSpec()
    {
        Describe<Foo>(() =>
        {
            Describe(nameof(Foo.Bar), () =>
            {
                Describe("when x is y", () =>
                {
                });
            });
        });
    }
}

<a id="its"></a>

Its (tests)

Now that you've specified the scopes for the class, method and (optionally) scenarios for your test, it is time to start defining the test itself. This is done by using the It methods. Each test's description should begin with "should" since this yields readable test descriptions.

class FooSpec : Spec
{
    public FooSpec()
    {
        Describe<Foo>(() =>
        {
            Describe(nameof(Foo.Bar), () =>
            {
                It("should initialize the flux capacitor.", () =>
                {
                    ... // test logic here
                });
            });
        });
    }
}

The above test will yield the following test description:

Foo Bar should initialize the flux capacitor.

<a id="beforeAfterEach"></a>

BeforeEach and AfterEach

JazSharp allows you to specify logic that will execute before and after each test. This logic is scoped to the Describe in which it is defined. See the below code for an illustration of how the scoping works.

class FooSpec : Spec
{
    public FooSpec()
    {
        Describe<Foo>(() =>
        {
            BeforeEach(() =>        // before each 1
            {
                ...
            });

            Describe(nameof(Foo.Bar), () =>
            {
                It("should initialize the flux capacitor.", () => 
                {
                    // before each 1 will be run
                    // before each 2 will not be run
                    ... // test logic here
                });
            });

            Describe("something else", () =>
            {
                BeforeEach(() =>    // before each 2
                {
                    ...
                });
            });
        });
    }
}

Before and After Each can be defined anywhere inside the Describe - before each doesn't have to be declared before Its. It is recommended to have BeforeEach blocks at the start of a Descibe and AfterEach at the end in order to make the test code easier to follow.

Expectations (JazSharp's equivalent of Asserts - covered in a future section) can also be specified in Before and After Each blocks. This can allow you to have expectations shared among multiple tests.

<a id="excludingAndFocusing"></a>

Excluding and focusing

Sometimes there are tests cannot be safely re-run, are intentionally broken or are simply not relevant to pending work. In this case, it may be desirable to exclude those tests. Excluding is a simple matter of prefixing a Describe or It call with an "x". xDescribe and xIt result in a test being listed but running unit tests will result in a skipped status.

There may be other times, such as when working in a specific area or updating specific unit tests where explicity focusing those tests may be convenient. While the Test Explorer does make running specific tests easy, it is also possible to "focus" tests in JazSharp. Tests can be focused by adding an "f" prefix to a Describe or It call. If any tests are focused, only focused tests will be executed.

<a id="output"></a>

Custom Output

A test can add to the output log for a test by writing to the output StringBuilder. This is an optional first parameter that can be added to your test methods:

class FooSpec : Spec
{
	public FooSpec()
	{
		Describe<Foo>(() =>
		{
			It("should x y and z.", output => // output is of type StringBuilder
			{
				output.WriteLine("This is some extra test log output!");
			});
		});
	}
}

<a id="spying"></a>

Spying

<a id="whatAreSpies"></a>

What are spies

Spies are similar to mocks except that they are applied on a per-method basis. A spy is an alternative implementation of a method which records calls made to the method and allows the test to specify alternative behaviours of the methods.

<a id="behaviours"></a>

Behaviours

You can spy on a method by using the Jaz.SpyOn method. Once spied on, a method will not get executed. If the method is a function, the default value will be returned. If the method has Out parameters, these too will be defaulted.

var value = "test";
var spy = Jaz.SpyOn(value, nameof(value.ToString));
var result = value.ToString(); // result is null

You can also spy on static methods.

var spy = Jaz.SpyOn(typeof(string), nameof(string.IsNullOrEmpty));
var result = string.IsNullOrEmpty(null); // result is false

To keep the spy and execute the method's original implementation, use the CallThrough method.

var value = "test";
var spy = Jaz.SpyOn(value, nameof(value.ToString)).And.CallThrough();
var result = value.ToString(); // result is "test"

To instead return another value from the function, use the ReturnValue method.

var value = "test";
var spy = Jaz.SpyOn(value, nameof(value.ToString)).And.ReturnValue("other");
var result = value.ToString(); // result is "other"

You can also specify a sequence of return values that each subsequent call to the method will return. Once the sequence runs out, a JazSpyException will be thrown.

var value = "test";
var spy = Jaz.SpyOn(value, nameof(value.ToString)).And.ReturnValues("other", "value");
var result = value.ToString(); // result is "other"
result = value.ToString(); // result is "value"
value.ToString(); // throws exception

Alternatively, you can specify that the method should throw an exception. You can specify the exception either by passing in the instance:

var value = "test";
var exception = new InvalidOperationException();
var spy = Jaz.SpyOn(value, nameof(value.T
View on GitHub
GitHub Stars64
CategoryDevelopment
Updated3mo ago
Forks4

Languages

C#

Security Score

92/100

Audited on Dec 24, 2025

No findings