@blairconrad blairconrad released this May 25, 2016 · 991 commits to master since this release

This major release of FakeItEasy comes jam packed with new features, improvements and bug fixes.

Notably, a lot of work has gone into making FakeItEasy 2.0.0 thread-safe, for running tests in parallel, which is the default behavior of some of the latest versions of popular test frameworks such as xUnit.net. We're also excited about the simpler and more powerful API for configuring events. Now and Go are gone, and you can now raise events of any type (an often requested feature). The API as a whole has been streamlined significantly with many redundant features removed, inappropriate members hidden from Intellisense, and support for legacy platforms (.NET 3.5, Silverlight) removed. For full details of all changes in 2.0, see below.

Oh, we've also created a Roslyn Analyzer! The first diagnostic we've added warns you if you've made a call specification, e.g. A.CallTo(() => foo.Bar()) and then haven't done anything with it, e.g. .Returns(42). Look out for more diagnostics and code fixes to come!


We hope you enjoy using FakeItEasy 2.x as much as we've enjoyed building it!

Get the new release and the analyzer from NuGet now!


  • Raising custom event handler events now require a typeparam (but neither Now nor Go). (#30)
    For example:

      public delegate void CustomEventHandler(object sender, CustomEventArgs e);
      event CustomEventHandler CustomEvent;
      fake.CustomEvent += Raise.With<CustomEventHandler>(fake, sampleCustomEventArgs);

    To avoid this requirement, make CustomEvent an EventHandler<CustomEventArgs>.

  • Passing a null sender to Raise.With now raises an event with a null sender. Use Raise.With(TEventArgs) to raise with the Fake as the sender. (#395)

  • The old IFakeOptionsBuilder interface is now named IFakeOptions. A new IFakeOptionsBuilder interface was created to provide implicit fake configuration at time of creation. (#520, #461)

  • IFakeOptionsBuilder replaces IFakeConfigurator. IFakeOptionsBuilder is more flexible, and implementations can provide implicit creation options for multiple types of fakes. The interface has changed as well, allowing any of the fake creation options to be applied implicitly. (#402, #520):

    Priority Priority { get; }
    bool CanBuildOptionsForFakeOfType(Type type);
    void BuildOptions(Type typeOfFake, IFakeOptions options);
  • Fakes' methods act the same during fake creation as after. They return the same results, calls to them show up in MustHaveHappened, and they are subject to configuration during fake construction via explicit fake creation options or implicit fake creation options. (#371)

  • Fake creation option OnFakeCreated has been renamed to ConfigureFake to reflect that its effects are active during fake creation. (#454)

  • Fake creation options now have more predictable interactions (#467):

    • WithAdditionalAttributes stacks instead of overriding previous calls
    • Wrapping overrides CallsBaseMethods, Strict, and ConfigureFake, on the principle of "last action in wins"
  • IDummyDefinition and DummyDefinition<T> have been renamed to IDummyFactory and DummyFactory<T>. The factories are now more powerful, able to create more Dummy types from a single factory type, as the interface has changed. (#402, #441):

    bool CanCreate(Type);
    object Create(Type);
    Priority Priority {get};
  • Unconfigured get properties now return a Dummy, rather than trying to make a Fake first. This matches unconfigured methods' behaviour. (#156)

  • Unconfigured methods that return Lazy or Task of a non-Dummyable type now return a concrete Lazy or Task of the default value for the parameterized type, instead of a Fake Lazy or Task. (#560)

  • Ordered assertions are made using a new API. (#637):

    A.CallTo(() => unitOfWorkFactory.BeginWork()).MustHaveHappened()
        .Then(A.CallTo(() => usefulCollaborator.JustDoIt()).MustHaveHappened())
        .Then(A.CallTo(() => unitOfWork.Dispose()).MustHaveHappened());
  • IArgumentValueFormatter, IDummyFactory, and IFakeOptionsBuilder have all had their Priority member changed to be a new type, Priority, which can only be constructed with values 0255, with a special member Priority.Default equivalent to a priority of 0.

  • ArgumentCollection, IRepeatSpecification, and Raise have moved to the FakeItEasy.Configuration namespace. There should be no need to access these except as return values from API methods. (#432)

  • The IHideObjectMembers API support interface was moved to the FakeItEasy namespace. (#585)

Removed from public API

  • .NET 3.5, Silverlight, Windows8, and Windows8.1 support. (#217, #507)
  • Now and Go, formerly used when raising events. (#30)
  • Any and Configure types. Also the FakeItEasy.ExtensionSyntax namespace, which provided fake.Configure().CallsTo(…),
    fake.CallsTo(…). Use A.CallTo(…) instead. (#408, #410)
  • static methods A.Equals, A.ReferenceEquals, Fake.Equals, Fake.ReferenceEquals. Use corresponding methods on object instead. (#425)
  • ArgumentCollection.Empty (and class's constructors), ITypeCatalogue, TypeCatalogue, FakeManager.Factory and FakeManager's constructor, ICallCollectionAndCallMatcherAccessor, ICallMatcher, ICallMatcherAccessor, ProxyGeneratorResult. All known uses for these were internal to the
    library. (#428)
  • IFakeObjectCallRuleWithDescription. No known uses. (#410)
  • ConditionalWeakTable, InheritedExportAttribute, ImportManyAttribute, and Tuple classes, as well as the
    Zip and FirstFromEachKey enumerable extension methods. These were always intended for internal use only. (#565)
  • IFakeObjectContainer, IFakeObjectOptionsBuilder, DelegateFakeObjectContainer, DynamicContainer, NullFakeObjectContainer, and Fake Scope creation methods that allowed the user to supply an IFakeObjectContainer. (#603)
  • IFakeScope, Fake.CreateScope. Fake Scopes are no longer supported. (#604)
  • NextCall is no longer supported, and has been removed. As a result, IInterceptedFakeObjectCall.DoNotRecordCall, and IWritableFakeObjectCall provided no value and have been removed. (#642)


  • Improved exception thrown when fake's base's constructor fails. (#367)
  • Returning the same object on subsequent auto-property gets even when the property type is not fakeable. (#312)
  • No longer throwing NullReferenceException when trying to fake a non-virtual generic method method. (#480)
  • No longer attempting to load Bootstrapper from dynamic assemblies. (#561)
  • AssignsOutAndRefParameters now works properly with faked delegates. (#677)


  • Can now raise events of arbitrary delegate type. (#30)
  • Dummy Lazy<T> values now default to having a value (which is a Dummy of type T). (#358)
  • Implements now has a generic overload: Implements<IAmAnInterface>(). (#470)
  • Better threadsafety when using That.Matches or Ignored argument constraints. (#476)
  • Better threadsafety for ArgumentValueFormatter. (#500)
  • Fakes now record and assert received calls in a threadsafe manner. (#600)
  • The Implements fake creation option throws an exception when passed a non-interface. (#462)
  • Redefining a rule's behavior throws an informative error. (#534)
  • That and IFakeOptions<T> hide members inherited from object, making for a better fluent syntax. (#580, #583)
  • A<T>.That, A<T>.Ignored, and A<T>._, throw an exception when invoked outside of A.CallTo. (#559)
  • Use A.CallToSet with a read-write property to configure the setter. (#175)
  • Use A.CollectionOfDummy<T>() to create a collection of dummies. (#675)
  • (Analyzer) Diagnostic for unused call specification. (#490)

With special thanks for contributions to this release from: