Question

I am working on a Prism template for my company. I want to make design time data as easy to do as possible.

To that end, I am making a Design class that inherits from my ViewModel. The DesignViewModel will call the constructor of my ViewModel.

My ViewModel constructors sometimes make calls prism methods and properties like IRegionManager.Regions. I am thinking of making a Stub for that interface that will use NSubstitute. Like this:

public class DesginRegionManager : IRegionManager
{
    public IRegionManager CreateRegionManager(){return this;}

    private readonly IRegionCollection regions;
    public DesginRegionManager()
    {
        regions = Substitute.For<IRegionCollection>();   <--------
    }                                                            |
                                                                 |
    public IRegionCollection Regions {get { return regions; }}   |
}                                                                |
                                                                 |
// Using NSubstitute here ----------------------------------------

I am planning to do similar stuff for IUnityContainer.

I have never used a Mocking framework in anything but unit tests before. Is it a bad idea to use it like this?

Though it will never be called in production code, it will add a dependency on NSubstitute for my actual application.

Are there drawbacks to this?

Was it helpful?

Solution

Before continuing, I have very little experience with Prism although I have worked with caliburn before so I am going to assume it works in similar manner. But I do have a little experience with nsubstitute.

Is it a bad idea to use substitutes for design purposes?

My short answer is no.

Is not entirely ideal but when you have a design department (or someone responsible for the UI elements while you continue coding) is a good practice to isolate the code executed by the UI from the design process as you will be able to improve over your interface even if the code to be executed on real time is buggy.

When I say substitutes I am talking about real (sample data like) instances to be created on design time by visual studio or blend. (I will provide a sample at the end).

Is it a bad idea to mock these elements?

Maybe not, although you will be including more dependencies to your project that aren't really that important for the execution of it.

The positive side of it is:

Mocked definitions means you will be maintaining less code, but you won't be able to simulate data over these fake instances (or won't unless you start returning sample data for each mock).

The negative side of this:

First, depending on the mocking framework you will be loading (on design time) instances of proxies or fakes created on the fly to simulate certain behaviour intercepting calls and other stuff. It could be a painful operation if you create tons and tons of objects that aren't as lightweight as the real code.

Besides your designer (in case of having one blend guru) will have to gather the knowledge of how the hell nsubstitute (or the mocking framework of your preference) works.

If I had a designer cap and you show me a class with certain definition that I could replicate versus the class defined with an external library called substitute I might tell you I prefer the first option as I won't have the need to learn anything else other than a bit of c#. And even like that I won't try to touch that code.

Any drawbacks of adding nsubstitute to your project?

As long as you are using DesignInstance correctly and the reference of the code with mocks is isolated from the actual functionality and you are not trying to substitute non virtual properties, or instances with multiple parameters or sealed classes (basically any restriction of nsubstitute over what to substitute) you will be fine as the design attributes will be executed under a special mode of your code.

NSubstitute in particular might throw exceptions trying to create the instance or accessing certain property in which case the IDE may crash or crashes control while loading it.

Any samples?

You probably know what to write, but here it goes (not prism though).

<UserControl
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/winfx/expression/blend/2008"
    xmlns:vm="clr-namespace:Project.Namespace.ViewModels.DataSamples"
    d:DataContext="{d:DesignInstance IsDesignTimeCreatable=True, Type={x:Type NationViewModelSampleData}}">

    <StackPanel DataContext="{Binding Leader}">
        <TextBlock Text="{Binding FirstName}" />
        <TextBlock Text="{Binding LastName}" />
    </StackPanel>
</UserControl>

Where the NationViewModel implemented an interface like this

namespace Project.Namespace.ViewModels
{
    public interface INationViewModel
    {
        IPerson Leader { get; }
        IEnumerable<IPerson> Citizens { get; }
    }

    public interface IPerson
    {
        string FirstName { get; }
        string LastName { get; }
    }
}

And the sample data is:

namespace Project.Namespace.ViewModels.DataSamples
{
    public class NationViewModelSampleData : Project.Namespace.ViewModels.INationViewModel
    {
        public NationViewModelSampleData()
        {
            // You could have done something like this as well, but for this sample was more code to write.
            // Leader = Substitute.For<IPerson>();
            // Leader.FirstName.Returns("John");
            // Leader.LastName.Returns("Doe");
            // or just...
            Leader = new Person { FirstName = "John", LastName = "Doe" };

            Citizens = new IPerson[]
                       {
                           new Person { FirstName = "Malcolm", LastName = "Little" },
                           Leader
                       };
            // You could have applied the mock to this section as well... again, more code for this scenario than just a simple real instance.
        }

        public IPerson Leader { get; private set; }
        public IEnumerable<IPerson> Citizens { get; private set; } 
    }
}

In this sample I have decided to go with the actual instances because my imaginary implementation of Person is pretty small and safe to use... but I expect it to grow in complexity I might want to cut that slack as well and just implement my PersonSampleData instance or mock it as you described before.

Hope this comment is helpful.

Cheers!

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top