New to Telerik JustMock? Download free 30-day trial

Future Mocking

Future Mocking allows you to mock members without passing the dependency through a constructor or calling a method. You can apply future mocking automatically based on an expectation rather than applying it to every instance explicitly. You will find this handy, especially in cases when you have to mock third party controls and tools where you have little control over how they are created.

Ignore instance for an expectation explicitly

By default, all mocks are tied to an instance and this is the expected behavior. The instance that we created in the following sample is an object of type UserData, which has a single method called ReturnFive() which returns an integer. Then we mock the call to the ReturnFive() method for the fakeUsed instance of the UserData class. But note that the ReturnFive() method will not be mocked for any of the other instances of the UserData class.

public class UserData 
{ 
    public int ReturnFive() 
    { 
        return 5; 
    } 
} 
 
[TestMethod] 
public void ShouldArrangeReturnOnlyForSpecificInstance() 
{ 
    // Arrange 
    var fakeUsed = Mock.Create<UserData>(); 
    Mock.Arrange(() => fakeUsed.ReturnFive()).Returns(7); 
 
    // Assert 
    Assert.AreEqual(7, fakeUsed.ReturnFive()); 
    Assert.AreEqual(5, new UserData().ReturnFive());     
} 
Public Class UserData 
    Public Function ReturnFive() As Integer 
        Return 5 
    End Function 
End Class 
 
<TestMethod> 
Public Sub ShouldArrangeReturnOnlyForSpecificInstance() 
    ' Arrange 
    Dim fakeUsed = Mock.Create(Of UserData)() 
    Mock.Arrange(Function() fakeUsed.ReturnFive()).Returns(7) 
 
    ' Assert 
    Assert.AreEqual(7, fakeUsed.ReturnFive()) 
    Assert.AreEqual(5, New UserData().ReturnFive()) 
End Sub 

If we want to apply future mocking and assure that all UserData instances use the same mocked version of the ReturnFive() method, we can call IgnoreInstance().

[TestMethod] 
public void ShouldArrangeReturnForFutureUserDataInstances() 
{ 
    // Arrange 
    var fakeUsed = Mock.Create<UserData>(); 
    Mock.Arrange(() => fakeUsed.ReturnFive()).IgnoreInstance().Returns(7); 
 
    // Assert 
    Assert.AreEqual(7, fakeUsed.ReturnFive()); 
    Assert.AreEqual(7, new UserData().ReturnFive()); 
} 
<TestMethod> 
Public Sub ShouldArrangeReturnForFutureUserDataInstances() 
    ' Arrange 
    Dim fakeUsed = Mock.Create(Of UserData)() 
    Mock.Arrange(Function() fakeUsed.ReturnFive()).IgnoreInstance().Returns(7) 
 
    ' Assert 
    Assert.AreEqual(7, fakeUsed.ReturnFive()) 
    Assert.AreEqual(7, New UserData().ReturnFive()) 
End Sub 

When IgnoreInstance is applied, the ReturnFive() method will work according to the expectation you have set in Mock.Arrange.

When setting future expectations, you can also use the Fluent Mocking API as in this example:

[TestMethod] 
public void ShouldArrangeReturnForFutureUserDataInstances_Fluent() 
{ 
    // Arrange 
    var fakeUsed = Mock.Create<UserData>(); 
    fakeUsed.Arrange(mock => mock.ReturnFive()).IgnoreInstance().Returns(7); 
 
    // Assert 
    Assert.AreEqual(7, fakeUsed.ReturnFive()); 
    Assert.AreEqual(7, new UserData().ReturnFive()); 
} 
<TestMethod> 
Public Sub ShouldArrangeReturnForFutureUserDataInstances_Fluent() 
    ' Arrange 
    Dim fakeUsed = Mock.Create(Of UserData)() 
    fakeUsed.Arrange(Function(x) x.ReturnFive()).IgnoreInstance().Returns(7) 
 
    ' Assert 
    Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AreEqual(7, fakeUsed.ReturnFive()) 
    Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AreEqual(7, New UserData().ReturnFive()) 
End Sub 

Using IgnoreInstance for Virtual Methods

You can also apply IgnoreInstance to virtual methods. Imagine that we have a simple class Calculus which has a virtual method Sum:

public class Calculus 
{ 
    public virtual int Sum() 
    { 
        return 0; 
    } 
} 
Public Class Calculus 
    Public Overridable Function Sum() As Integer 
        Return 0 
    End Function 
End Class 

Now we can use IgnoreInctance in the exact same way:

[TestMethod] 
public void ShouldApplyIgnoreInstanceToVirtual() 
{ 
    //Arrange 
    var calculus = Mock.Create<Calculus>(); 
    Mock.Arrange(() => calculus.Sum()).IgnoreInstance().Returns(10); 
 
    //Assert 
    Assert.AreEqual(10, calculus.Sum()); 
    Assert.AreEqual(10, new Calculus().Sum()); 
} 
<TestMethod> 
Public Sub ShouldApplyIgnoreInstanceToVirtual() 
    'Arrange 
    Dim calculus = Mock.Create(Of Calculus)() 
    Mock.Arrange(Function() calculus.Sum()).IgnoreInstance().Returns(10) 
 
    'Assert 
    Assert.AreEqual(10, calculus.Sum()) 
    Assert.AreEqual(10, New Calculus().Sum()) 
End Sub 

Using IgnoreInstance for Collections

In the following example, we want to Arrange a property to return a fake collection. To demonstrate this, we will use the Foo class below.

public class Foo 
{ 
    public Foo() 
    { 
    } 
 
    public List<object> RealCollection 
    { 
        get { return collection; } 
    } 
    private List<object> collection; 
} 
Public Class Foo 
    Public Sub New() 
    End Sub 
 
    Public ReadOnly Property RealCollection() As List(Of Object) 
        Get 
            Return collection 
        End Get 
    End Property 
    Private collection As List(Of Object) 
End Class 

We will also use a public method that returns our fake collection.

public IList<object> FakeCollection() 
{ 
    List<object> resultCollection = new List<object>(); 
 
    resultCollection.Add("asd"); 
    resultCollection.Add(123); 
    resultCollection.Add(true); 
 
    return resultCollection; 
} 
Public Function FakeCollection() As IList(Of Object) 
    Dim resultCollection As New List(Of Object)() 
 
    resultCollection.Add("asd") 
    resultCollection.Add(123) 
    resultCollection.Add(True) 
 
    Return resultCollection 
End Function 

This is how the test will look like:

[TestMethod] 
public void ShouldReturnFakeCollectionForFutureCall() 
{ 
    var fooMocked = Mock.Create<Foo>(); 
 
    var expectedCollection = FakeCollection(); 
 
    // Arrange 
    Mock.Arrange(() => fooMocked.RealCollection).IgnoreInstance().ReturnsCollection(expectedCollection); 
 
    // Act 
    var actualArrangedCollection = fooMocked.RealCollection; 
    var actualUnArrangedCollection = new Foo().RealCollection; 
 
    // Assert 
    // Asserting for the arranged instance 
    Assert.AreEqual(expectedCollection.Count, actualArrangedCollection.Count); 
    Assert.AreEqual(expectedCollection.FirstOrDefault(), actualArrangedCollection.FirstOrDefault()); 
 
    // Asserting for a new unarranged instance 
    Assert.AreEqual(expectedCollection.Count, actualUnArrangedCollection.Count); 
    Assert.AreEqual(expectedCollection.FirstOrDefault(), actualUnArrangedCollection.FirstOrDefault()); 
} 
<TestMethod> 
Public Sub ShouldReturnFakeCollectionForFutureCall() 
    Dim fooMocked = Mock.Create(Of Foo)() 
 
    Dim expectedCollection = FakeCollection() 
 
    ' Arrange 
    Mock.Arrange(Function() fooMocked.RealCollection).IgnoreInstance().ReturnsCollection(expectedCollection) 
 
    ' Act 
    Dim actualArrangedCollection = fooMocked.RealCollection 
    Dim actualUnArrangedCollection = New Foo().RealCollection 
 
    ' Assert 
    ' Asserting for the arranged instance 
    Assert.AreEqual(expectedCollection.Count, actualArrangedCollection.Count) 
    Assert.AreEqual(expectedCollection.FirstOrDefault(), actualArrangedCollection.FirstOrDefault()) 
 
    ' Asserting for a new unarranged instance 
    Assert.AreEqual(expectedCollection.Count, actualUnArrangedCollection.Count) 
    Assert.AreEqual(expectedCollection.FirstOrDefault(), actualUnArrangedCollection.FirstOrDefault()) 
End Sub 

You can see that the test logic is the same as in the previous tests, with the only difference that you are returning a collection this time.

Future Constructor Mocking

With JustMock you are even able to future mock the constructor of an instance. Let`s assume we have the following class:

public class FooWithNotImplementedConstructor 
{ 
    public FooWithNotImplementedConstructor() 
    { 
        throw new NotImplementedException(); 
    } 
} 
Public Class FooWithNotImplementedConstructor 
    Public Sub New() 
        Throw New NotImplementedException() 
    End Sub 
End Class 

We can easily arrange its constructor like this:

[TestMethod] 
public void ShouldMockConstructorForFutureInstances() 
{ 
    // Arrange 
    Mock.Arrange(() => new FooWithNotImplementedConstructor()).DoNothing(); // Directly arranging the constructor 
 
    // Act 
    var myNewInstance = new FooWithNotImplementedConstructor(); // This will not throw an exception 
 
    // Assert 
    Assert.IsNotNull(myNewInstance); 
    Assert.IsInstanceOfType(myNewInstance, typeof(FooWithNotImplementedConstructor)); 
} 
<TestMethod> 
Public Sub ShouldMockConstructorForFutureInstances() 
    ' Arrange 
    Mock.Arrange(Function() New FooWithNotImplementedConstructor()).DoNothing() ' Directly arranging the constructor 
 
    ' Act 
    Dim myNewInstance = New FooWithNotImplementedConstructor() ' This will not throw an exception 
 
    ' Assert 
    Assert.IsNotNull(myNewInstance) 
    Assert.IsInstanceOfType(myNewInstance, GetType(FooWithNotImplementedConstructor)) 
End Sub 

This will apply DoNothing to the constructor of every new instance of type FooWithNotImplementedConstructor called during the test method.

Mocking the New Operator

With JustMock, you can arrange a return value for a new object creation. Let's assume we have the following class:

public class FooWithProp 
{ 
    public string MyProp { get; set; } 
} 
 
public FooWithProp GetNewInstance() 
{ 
    return new FooWithProp(); 
} 
Public Class FooWithProp 
    Public Property MyProp As String 
End Class 
 
Public Function GetNewInstance() As FooWithProp 
    Return New FooWithProp() 
End Function 

We can easily arrange each new instance of the FooWithProp class, to return a predefined object of the same type:

[TestMethod] 
public void ShouldReturnNewObjectForFutureInstances() 
{ 
    // Arrange 
    var testObj = new FooWithProp() { MyProp = "Test" }; 
 
    // Directly arranging the expression to return our predefined object 
    Mock.Arrange(() => new FooWithProp()).Returns(testObj);  
 
    // Act 
    var myNewInstance = GetNewInstance(); 
 
    // Assert 
    Assert.IsNotNull(myNewInstance); 
    Assert.IsInstanceOfType(myNewInstance, typeof(FooWithProp)); 
    // Assert that the returned instance is equal to the predefined 
    Assert.AreEqual("Test", myNewInstance.MyProp); 
} 
<TestMethod> 
Public Sub ShouldReturnNewObjectForFutureInstances() 
    ' Arrange 
    Dim testObj = New FooWithProp() 
    testObj.MyProp = "Test" 
 
    ' Directly arranging the expression to return our predefined object 
    Mock.Arrange(Function() New FooWithProp()).Returns(testObj) 
 
    ' Act 
    Dim myNewInstance = GetNewInstance() 
 
    ' Assert 
    Assert.IsNotNull(myNewInstance) 
    Assert.IsInstanceOfType(myNewInstance, GetType(FooWithProp)) 
    ' Assert that the returned instance is equal to the predefined 
    Assert.AreEqual("Test", myNewInstance.MyProp) 
End Sub 

This will work for each new instance of the FooWithProp type outside the test method. Still, it applies only for code, executed under the test context.

Future Mocking Across Threads

Future mocking across all threads is an unsafe operation because it may compromise the stability of the testing framework. Arrangements that ignore the instance are valid only for the current thread by default. To make an arrangement that ignores the instance valid on all threads, add the .OnAllThreads() clause to the arrangement:

Mock.Arrange(() => new DBContext()).DoNothing().OnAllThreads(); 
Mock.Arrange(Function() New DBContext()).DoNothing().OnAllThreads() 

Advanced Example

Let's see a UI example where we have a form. Based on some action against the form, it raises an event that needs to be handled in a specific way, therefore in the unit test we want to assert the expected value of the handler execution.

public Form() 
{ 
  InitializeComponent(); 
 
  this.service = new EntryService(); 
 
  service.Saved += new EventHandler<EntrySavedEventArgs>(service_Saved); 
} 
Public Sub New() 
    InitializeComponent() 
    Me.service = New EntryService() 
    service.Saved += New EventHandler(Of EntrySavedEventArgs)(service_Saved) 
End Sub 

Imagine that we have defined an EntryService the purpose of which is to save some entries to a database when the user has made any changes. For instance, we can have a button on the form, and when the user finishes editing the entries, pressing this button will trigger a call to the following method:

public void SaveToDatabase(string value) 
{ 
  try 
  { 
    this.service.Save(value); 
  } 
  catch (DuplicateEntryException ex) 
  { 
    MessageBox.Show("Entry Duplicated " + ex.DuplicatedValue); 
  } 
} 
Public Sub SaveToDatabase(ByVal value As String) 
    Try 
        Me.service.Save(value) 
    Catch ex As DuplicateEntryException 
        MessageBox.Show("Entry Duplicated " & ex.DuplicatedValue) 
    End Try 
End Sub 

Here is the handler for the service.Saved event:

public void service_Saved(object sender, EntrySavedEventArgs e) 
{ 
  this.label1.Text = "Saved string : " + e.EntryValue; 
} 
Public Sub service_Saved(ByVal sender As Object, ByVal e As EntrySavedEventArgs) 
    Me.label1.Text = "Saved string : " & e.EntryValue 
End Sub 

Next, is a simple test using MSpec where we have created an event handler that will receive as an argument the value that was passed to the service.Save call in the SaveToDatabase method.

[Subject(typeof(Form))] 
public class when_save_to_database_is_invoked_on_form 
{ 
    Establish context = () => 
    { 
        IEntryService serviceMock = Mock.Create<EntryService>(); 
        Mock.Arrange(() => serviceMock.Save(valueToSave)).Raises(() => serviceMock.Saved += null, new EntrySavedEventArgs(valueToSave)); 
    }; 
 
    private Because of = () => 
    { 
        sut = new Form(); 
        sut.SaveToDatabase(valueToSave); 
    }; 
 
    private It should_assert_that_label_contains_expected_valueToSave = () => 
        sut.label1.Text.ShouldEqual("Saved string : " + valueToSave); 
 
    static Form sut; 
    const string valueToSave = "Raise Event"; 
} 
<Subject(GetType(Form))> 
Public Class when_save_to_database_is_invoked_on_form 
    Private context As Establish = Function() 
                                      Dim serviceMock As IEntryService = Mock.Create(Of EntryService)() 
                                      Mock.Arrange(Function() serviceMock.Save(valueToSave)).Raises(Function() CSharpImpl.__Assign(serviceMock.Saved, Nothing), New EntrySavedEventArgs(valueToSave)) 
                                  End Function 
 
    Private [of] As Because = Function() 
                                  sut = New Form() 
                                  sut.SaveToDatabase(valueToSave) 
                              End Function 
 
    Private should_assert_that_label_contains_expected_valueToSave As It = Function() sut.label1.Text.ShouldEqual("Saved string : " & valueToSave) 
    Shared sut As Form 
    Const valueToSave As String = "Raise Event" 
 
    Private Class CSharpImpl 
        <Obsolete("Please refactor calling code to use normal Visual Basic assignment")> 
        Shared Function __Assign(Of T)(ByRef target As T, value As T) As T 
            target = value 
            Return value 
        End Function 
    End Class 
End Class 

Here we can see that although no instance is supplied to the target UI class, JustMock picks up the intended setup from the context.

See Also

In this article
Not finding the help you need? Improve this article