Search Results for

    Show / Hide Table of Contents

    Testing code with the OpenFin .NET Adapter

    With the implementation of the adapter for .NET 6+, it is possible to write unit tests that mock various aspects of the adapter.

    The features that enable this functionality include:

    • Builder-style runtime creation
    • A mockable type resolution service
    • Returning interfaces from creation methods rather than concrete types

    An example

    This example assumes you have a simple model class that reacts to Interop context changes by setting a property with a field from the context payload.

    Ideally you want to write unit test this in isolation of OpenFin by passing in a variety of scenarios to the context receiver and asserting that the model handles these as expected.

    Based on the example below, you can learn how to invoke your own code using mock .NET adapter objects, without any need to write your own wrapper around the adapter or running an actual OpenFin Runtime during tests.

    The code to be tested

    For the purposes of this example, the model class looks like the followingL

    internal class MainWindowVM
    {
        private readonly IRuntime runtime;
        private IChannelClient channelClient;
    
        public string CurrentId { private set; get; }
    
        // Pass in the runtime interface when creating the model
        public MainWindowVM(IRuntime runtime)
        {
            this.runtime = runtime;
    
            // Connect to the broker and add a handler for a context change
            var interop = runtime.GetService<IInterop>();
            interopClient = await interop.ConnectAsync("the-broker");        
    
            await interopClient.AddContextHandlerAsync(HandleContext, "my-context");
        }
    
        private void HandleContext(Context context)
        {
            if (context.Type == "fdc3.contact")
            {
                if ((context.Id as JsonObject).TryGetPropertyValue("email", out var valueNode))
                {
                    CurrentId = valueNode.ToString();
                }
            }
        }    
    }
    

    The tests

    The following example shows a simple test that checks that the CurrentId property within the model is updated only on an FDC3 contact context change.

    Note

    This example uses the popular MOQ library for mocking. You can use any mocking library that you prefer such as Rhino Mocks.

    [TestClass]
    public class InteropTests
    {
        [TestMethod]
        public void TestCurrentIdIsCorrectlySetAfterAContextChange()
        {
            // Set up the mocks
            ContextHandler contextHandler = null;
    
            // Create a mock for IRuntime
            var runtimeMock = new Mock<IRuntime>();
    
            // Create a mock for the entire IInterop API
            var interopMock = new Mock<IInterop>();
    
            // Set up the IRuntime so that when the model asks for IInterop it returns a mock
            runtimeMock.Setup(x => x.GetService<IInterop>())
                       .Returns(interopMock.Object);
    
            // Create a mock for the entire IInteropClient API
            var interopClientMock = new Mock<IInteropClient>();
            
            // Create a set up on the IInterop mock for when the model connects to the broker 
            // Return the previously created IInteropClient mock
            interopMock.Setup(x => x.ConnectAsync("the-broker"))
                       .ReturnsAsync( interopClientMock.Object );
    
            // When the model adds a handler for a context change, the test intercepts it and stores
            // the handler so to invoke directly later
            interopClientMock.Setup(x => x.AddContextHandlerAsync(It.IsAny<ContextHandler>(), "my-context"))
                             .Callback((ContextHandler handler, string contextType) =>
                             {
                                 contextHandler = handler;
                             });
    
            // Test the model:
    
            // Create the model and give it the runtime mock.
            // This in turn connects to the broker and invokes the various setups above
            var vm = new MainWindowVM(runtimeMock.Object);
    
            // The context handler is ready to invoke directly with a dummy context
            Assert.IsNotNull(contextHandler, "AddContextHandler should have been called by this point");
    
            // Set an initial context
            contextHandler(new Context
            {
                Type = "fdc3.contact",
                Id = new JsonObject
                        {
                            { "email", "username@example.com" }
                        }
            });
    
            Assert.AreEqual("username@example.com", vm.CurrentId);
    
            // Change it
            contextHandler(new Context
            {
                Type = "fdc3.contact",
                Id = new JsonObject
                        {
                            { "email", "anotheruser@example.com" }
                        }
            });
    
            // Should have changed
            Assert.AreEqual("anotheruser@example.com", vm.CurrentId);
    
            // Fire a context that is a different context type
            contextHandler(new Context
            {
                Type = "fdc3.instrument",
                Id = new JsonObject
                        {
                            { "isin", "abcdefg123" }
                        }
            });
    
            // Should have ignored this update
            Assert.AreEqual("anotheruser@example.com", vm.CurrentId);
        }
    }
    
    In This Article
    Back to top Copyright OpenFin