New to Telerik JustMock? Download free 30-day trial

Mocking Chained Calls

This feature enables you to mock members that are obtained as a result of "chained" calls on a mock. For example, mocking chained calls is useful in the cases when you test code like this: foo.Bar.Baz.Do("x").

In the next examples, we will use the following sample code to test:

Sample setup

public interface IFoo 
{ 
    IBar Bar { get; set; } 
    string Do(string command); 
} 
 
public interface IBar 
{ 
    int Value { get; set; } 
    string Do(string command); 
    IBaz Baz { get; set; } 
} 
 
public interface IBaz 
{ 
    string Do(string command); 
} 
Public Interface IFoo 
    Property Bar() As IBar 
    Function Do As String 
End Interface 
 
Public Interface IBar 
    Property Value() As Integer 
    Function Do As String 
    Property Baz() As IBaz 
End Interface 
 
Public Interface IBaz 
    Function Do As String 
End Interface 

How to Mock Chain of Method Calls

Consider the above code. Let's arrange that a call to IFoo.Do method returns a particular string. IFoo contains an IBar which, in turn, also contains a Do method. IBar.Do method can be accessed via a nested call to IFoo.Bar. To arrange the call directly from IFoo, we just need to chain it considering the fact that JustMock will automatically create the necessary mock for IBar.

Example 1: Mocking chain of method calls example

[TestMethod] 
public void ShouldAssertNestedVeriables() 
{ 
    // Arrange 
    var foo = Mock.Create<IFoo>(); 
 
    string ping = "ping"; 
 
    Mock.Arrange(() => foo.Do(ping)).Returns("ack"); 
    Mock.Arrange(() => foo.Bar.Do(ping)).Returns("ack2"); 
 
    // Act 
    var actualFooDo = foo.Do(ping); 
    var actualFooBarDo = foo.Bar.Do(ping); 
 
    // Assert 
    Assert.AreEqual("ack", actualFooDo); 
    Assert.AreEqual("ack2", actualFooBarDo); 
} 
<TestMethod()> 
Public Sub ShouldAssertNestedVeriables() 
    ' Arrange 
    Dim foo = Mock.Create(Of IFoo)() 
 
    Dim ping As String = "ping" 
 
    Mock.Arrange(Function() foo.Do(ping)).Returns("ack") 
    Mock.Arrange(Function() foo.Bar.Do(ping)).Returns("ack2") 
 
    ' Act 
    Dim actualFooDo = foo.Do(ping) 
    Dim actualFooBarDo = foo.Bar.Do(ping) 
 
    ' Assert 
    Assert.AreEqual("ack", actualFooDo) 
    Assert.AreEqual("ack2", actualFooBarDo) 
End Sub 

Note: If foo.Bar is not arranged, it will still be instantiated. Example 2 shows how you can verify that.

Example 2: Verifying object instantiation

[TestMethod] 
public void ShouldNotInstantiateFooBar() 
{ 
    // Arrange 
    var foo = Mock.Create<IFoo>(); 
 
    // Assert 
    Assert.IsNotNull(foo.Bar); 
} 
<TestMethod()> 
Public Sub ShouldNotInstantiateFooBar() 
    ' Arrange 
    Dim foo = Mock.Create(Of IFoo)() 
 
    ' Assert 
    Assert.IsNotNull(foo.Bar) 
End Sub 

Nested Property Calls

This section shows how to arrange the getter and setter of a nested property. All you need to do is to specify the property as you would do in real cases. JustMock will automatically setup all the requirements for the member like, for example, instantiating other objects in the chain.

Example 3: Arrange the getter of a nested property

[TestMethod] 
public void ShouldAssertNestedPropertyGet() 
{ 
    // Arrange 
    var foo = Mock.Create<IFoo>(); 
    Mock.Arrange(() => foo.Bar.Value).Returns(10); 
 
    // Act 
    var actual = foo.Bar.Value; 
 
    // Assert 
    Assert.AreEqual(10, actual); 
} 
<TestMethod()> 
Public Sub ShouldAssertNestedPropertyGet() 
    ' Arrange 
    Dim foo = Mock.Create(Of IFoo)() 
 
    Mock.Arrange(Function() foo.Bar.Value).Returns(10) 
 
    ' Act 
    Dim actual = foo.Bar.Value 
 
    ' Assert 
    Assert.AreEqual(10, actual) 
End Sub 

Here we arrange foo.Bar.Value to return 10.

You can also arrange the setter of a nested property. In Example 4, you will see how to arrange a nested property setter in scenario with Strict behavior. When using that behavior, you are allowed to call only arranged members and all other calls throw exception. If you need more details on this setup, check the Strict behavior topic.

Example 4: Arrange the setter of a nested property

[TestMethod] 
[ExpectedException(typeof(StrictMockException))] 
public void ShouldAssertNestedPropertySet() 
{ 
    // Arrange 
    var foo = Mock.Create<IFoo>(Behavior.Strict); 
 
    Mock.ArrangeSet(() => { foo.Bar.Value = 5; }).DoNothing(); 
 
    // Act 
    foo.Bar.Value = 5; 
    foo.Bar.Value = 10; // This line will throw MockException. The mocking behavior is Strict and only foo.Bar.Value = 5 is arranged and allowed. 
} 
<TestMethod()> 
<ExpectedException(GetType(StrictMockException))> 
Public Sub ShouldAssertNestedPropertySet() 
    ' Arrange 
    Dim foo = Mock.Create(Of IFoo)(Behavior.Strict) 
 
    Mock.ArrangeSet(Function() foo.Bar.Value = 5).DoNothing() 
 
    ' Act 
    foo.Bar.Value = 5 
    foo.Bar.Value = 10 ' This line will throw MockException. The mocking behavior is Strict and only foo.Bar.Value = 5 is arranged and allowed. 
End Sub 

We use Bahavior.Strict to enable only arranged calls and to reject any other calls. Only setting foo.Bar.Value to 5 is allowed and as we set it to 10, an exception will be thrown.

Nested Method Calls

Similarly to the nested properties, you can also arrange nested methods.

Example 5: Arrange the behavior of a nested method

[TestMethod] 
public void NestedPropertyAndMethodCalls() 
{ 
    // Arrange 
    var foo = Mock.Create<IFoo>(); 
 
    Mock.Arrange(() => foo.Bar.Do("x")).Returns("xit"); 
    Mock.Arrange(() => foo.Bar.Baz.Do("y")).Returns("yit"); 
 
    // Act 
    var actualFooBarDo = foo.Bar.Do("x"); 
    var actualFooBarBazDo = foo.Bar.Baz.Do("y"); 
 
    // Assert 
    Assert.AreEqual("xit", actualFooBarDo); 
    Assert.AreEqual("yit", actualFooBarBazDo); 
} 
<TestMethod()> 
Public Sub ShouldAssertNestedPropertyHavingMethods() 
    ' Arrange 
    Dim foo = Mock.Create(Of IFoo)() 
 
    Mock.Arrange(Function() foo.Bar.Do("x")).Returns("xit") 
    Mock.Arrange(Function() foo.Bar.Baz.Do("y")).Returns("yit") 
 
    ' Act 
    Dim actualFooBarDo = foo.Bar.Do("x") 
    Dim actualFooBarBazDo = foo.Bar.Baz.Do("y") 
 
    ' Assert 
    Assert.AreEqual("xit", actualFooBarDo) 
    Assert.AreEqual("yit", actualFooBarBazDo) 
End Sub 

In this arrangement we specify that foo.Bar.Do should return "xit" when invoked and foo.Bar.Baz.Do will always return "yit".

In this article