6

It's very easy to write unit tests for legacy code using unconstrained frameworks, such as TypeMock Isolator.

But what about writing unit tests for newly written code? Is it a good practice to use an unconstrained framework in such scenario? Or would a constrained framework (such as NSubstitute) enforce better software design?

Update: An unconstrained framework is a framework that can fake almost anything, including static classes, static constructors, and static methods. They make it possible for example to fake the result of DateTime.Now.

4
  • 1
    The terminology constrained / unconstrained framework is new to me. I see that it is used in the book "The Art of Unit Testing" but there are few "google" references other than it.
    – xanatos
    May 8 '15 at 7:52
  • 1
    The main problem is that, at this point, unconstrained frameworks (if they are what I think, Fakes/Moles for example) are hacks. Even when they are official hacks. And they aren't open source. They are commercial hacks. Microsoft one requires VS Premium or upper, the others are directly commercial products.
    – xanatos
    May 8 '15 at 7:55
  • I think the issue of needing an "unconstrained" mocking framework exposes architectural issues in the new code. If you are calling static classes and methods, you would be better off either not testing them if they are simple, or making them instantiable and testing those classes in isolation. Why do you need to mock things like static classes and methods, or DateTime.Now? May 8 '15 at 14:22
  • @Greg, please see answer below on why mocking DateTime.Now is necessary. I've included you questions in the answer as well.
    – Jon Raynor
    May 8 '15 at 15:50
1

Whether or not you need to use a unit testing framework is up to you. Any dependency will need to be faked so that logic can be tested in isolation. With legacy code where the dependencies are not visible a mocking or faking framework can help expose those dependencies for you and replace them so you can test that code easily without major refactoring.

In new/greenfield development, one can certainly not use a mocking framework if all the dependencies are exposed. This means that the developer is responsible for writing all the mocks instead of the framework generating them for you. You may decide its easier to let the framework inline those dependencies instead of the team writing the mocks/fakes manually.

If you don't want to use a framework, as an example consider calculating an age. This may also answer @Greg B question as well, why you would want to mock DateTime.Now. It needs the current time to calculate the age which will be difficult to produce consistent tests results since the current time changes.

Interface

public interface IClock
{
    DateTime Now { get; }
}

Real Implementation

public class SystemClock : IClock
{
    public DateTime Now { get { return DateTime.Now; } }
}

Class

public class DateLogic
{
    private readonly IClock _clock;

    public DateLogic(IClock clock)
    {
        _clock = clock;
    }
    public int CalculateAge(DateTime dateOfBirth)
    {
        DateTime now = _clock.Now;

        int age = now.Year - dateOfBirth.Year;
        if (now < dateOfBirth.AddYears(age)) age--;

        return age;
    }
}

Mock/Fake Clock

 public class MockClock200011 : IClock
    {
        public DateTime Now {get {return new DateTime(2000,1,1); } }
    }

Test

[TestMethod]
    public void TestCalculateAge()
    {
        var expected = 30;
        DateTime birthday = new DateTime(1969, 9, 11);
        IClock clock = new MockClock200011();
        var dateLogic = new DateLogic(clock);

        var actual = dateLogic.CalculateAge(birthday);

        Assert.AreEqual(expected, actual);
    }

So, in this case we wrote our own mock instead of having the framework do it and have put our age calculation in isolation. Doesn't matter what year/time, the test will produce the same results. I don't see any cons of using a framework besides cost and a dependency on that software. As one can see, you can get by without it provided the dependencies are exposed for mock/fake implementations.

5
  • I'm a little unclear on what this answer is trying to say. In particular, I don't know when you're referring to an unconstrained framework vs. a standard mocking library, which I think is the crux of the question May 8 '15 at 15:59
  • 1
    In my opinion, there is no difference (contrained/unconstrained) other than the amount of mocking features (what it can mock). If you have static methods and you need to mock them, then you will need a unconstrained framework to do that.
    – Jon Raynor
    May 8 '15 at 16:27
  • 2
    Or inject those static dependencies and mock them yourself. If you need an unconstrained framework to do unit testing, then yes, your code needs refactoring to eliminate those statics with side effects.
    – Jon Raynor
    May 8 '15 at 16:34
  • What about unit testing OO code, where you have a class which instantiates a stateful object of some other class? Many well-designed classes don't implement a separate interface, nor are they designed for extension by subclassing (therefore, they won't have virtual methods). To unit test the first class in isolation from the second, you either need an unconstrained mocking library, or you need to compromise the design to work around the limitations in a constrained mocking library.
    – Rogério
    May 11 '15 at 17:04
  • @Regerio - I concur with your comment(s).
    – Jon Raynor
    May 13 '15 at 17:39

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.