New to Telerik JustMock? Download free 30-day trial

Mock Static or Extension Members

Working with .NET applications enables you to use static classes, methods and properties. When a method is declared as static, it does not require an instance of its parent class so that it can be invoked — you can directly call it on the class itself.

Testing a non-static method (at least one that has a simple implementation without external dependencies) is straightforward. However, testing a static method is not an easy task at all. This article explains how you can overcome this challenge and test static classes and their members using JustMock.

Mocking static implementations is an elevated feature. Refer to the Commercial vs Free Version topic to learn more about the differences between both versions of Telerik JustMock.

To better illustrate different cases, we will be using several examples classes representing an order. The order can contain different products and it might have a gift for the user if they purchased more items. Here is how the implementation looks like:

Sample setup

public class Product 
{ 
    public Product(string name, int quantity) 
    { 
        this.Name = name; 
        this.Quantity = quantity; 
    } 
 
    public string Name { get; internal set; } 
    public int Quantity { get; internal set; } 
} 
 
public class Order 
{ 
    public Order(List<Product> products) 
    { 
        this.Products = products; 
    } 
 
    public List<Product> Products { get; private set; } 
    public bool IsCompleted { get; private set; } 
} 
 
public static class GiftsDistributor 
{ 
    public static int MinimalProductsCount { get; set; } 
    public static Product Gift { get; set; } 
 
    static GiftsDistributor() 
    { 
        MinimalProductsCount = 5; 
        Gift = new Product("Hat (gift)", 1); 
        EnsureGifts(Gift); 
    } 
 
    private static void EnsureGifts(Product gift) 
    { 
        // Contact the database to ensure warehouses have enough amount of the gift product to distribute between orders. 
        throw new NotImplementedException(); 
    } 
 
    public static void AddGift(Order order) 
    { 
        order.Products.Add(Gift); 
    } 
 
    public static bool IsEligibleForGift(Order order) 
    { 
        int currentProductsCount = 0; 
        foreach (var product in order.Products) 
        { 
            currentProductsCount += product.Quantity; 
        } 
 
        if (currentProductsCount >= MinimalProductsCount) 
        { 
            return true; 
        } 
 
        return false; 
    } 
} 

Mock Static Constructor

In the sample code above, you will notice that the constructor of GiftsDistributor invokes the EnsureGifts which in turn is used to contact the warehouses and ensure that they have enough amount of the products used as gifts for the future orders. The EnsureGifts method might need a connection to a specific service or database to do his job. This, however, is not a focus on the test we would like to implement – namely, to ensure that gifts are properly distributed for the orders. Here the static constructor mocking of JustMock comes handy to eliminate the dependencies we are not interested in.

The API of JustMock provides you with the SetupStatic method that prepares all the static members of a class and mocks its constructor.

Example 1: Mock a static object constructor

Mock.SetupStatic(typeof(GiftsDistributor), StaticConstructor.Mocked); 
With this method, you can specify whether you would like to mock the constructor or not and choose a mock behavior.

Mock Static Property

Once you set up the static type, you can mock its properties as you would do with instance properties.

Example 2: Mock a static property

Mock.Arrange(() => GiftsDistributor.MinimalProductsCount).Returns(0); 

Mock Static Method

Mocking static methods is also similar to how you mock instance methods. Just use the Mock.Arrange() method to setup the behavior you need.

Example 3: Mock a static method

Mock.SetupStatic(typeof(GiftsDistributor), StaticConstructor.Mocked); 
Order order = new Order(new List<Product>()); 
 
Mock.Arrange(() => GiftsDistributor.IsEligibleForGift(order)).Returns(true); 
// Ensure the original implementation of AddGift is being invoked 
Mock.Arrange(() => GiftsDistributor.AddGift(order)).CallOriginal(); 
GiftsDistributor.AddGift(order); 
 
// Assert  
// Ensure that a gift is added to the order 
Assert.AreEqual(1, order.Products.Count); 

Mock Extension Method

Extension methods in .NET are also defined as static ones. To demonstrate how you can mock extension methods, we will use the following sample implementation extending the functionality of the Order class.

Sample static class

public static class OrderExtensions 
{ 
    public static string PrintOrder(this Order order) 
    { 
        StringBuilder result = new StringBuilder(); 
        foreach (var product in order.Products) 
        { 
            result.AppendLine(string.Format("Purchased {0} {1}(s)", product.Quantity, product.Name)); 
        } 
 
        return result.ToString(); 
    } 
} 
To mock PrintOrder you would again need only to arrange your expectations with Mock.Arrange().

Example 4: Mock extension method

Order order = new Order(new List<Product>()); 
 
string expected = "Mocked"; 
Mock.Arrange(() => order.PrintOrder()).Returns(expected); 
 
string actual = order.PrintOrder(); 
 
Assert.AreEqual(expected, actual); 

Next Steps

Take a look at the Mock Non-Public API article that shows how you can setup private and internal implementations in your tests.

See Also

In this article