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);
}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);
}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);
}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);
}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.
}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);
}In this arrangement we specify that foo.Bar.Do should return "xit" when invoked and foo.Bar.Baz.Do will always return "yit".