diff --git a/src/Moq/It.cs b/src/Moq/It.cs index 716ed1d31..6a10c9fda 100644 --- a/src/Moq/It.cs +++ b/src/Moq/It.cs @@ -43,7 +43,12 @@ public static class Ref /// /// Typically used when the actual argument value for a method call is not relevant. /// - /// + /// + /// + /// // Throws an exception for a call to Remove with any string value. + /// mock.Setup(x => x.Remove(It.IsAny<string>())).Throws(new InvalidOperationException()); + /// + /// public static TValue IsAny() { if (typeof(TValue).IsTypeMatcher()) @@ -116,7 +121,22 @@ public static TValue IsNotNull() /// /// Allows the specification of a predicate to perform matching of method call arguments. /// - /// + /// + /// This example shows how to return the value 1 whenever the argument to + /// the Do method is an even number. + /// + /// mock.Setup(x => x.Do(It.Is<int>(i => i % 2 == 0))) + /// .Returns(1); + /// + /// + /// + /// This example shows how to throw an exception if the argument to the method + /// is a negative number: + /// + /// mock.Setup(x => x.GetUser(It.Is<int>(i => i < 0))) + /// .Throws(new ArgumentException()); + /// + /// [SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures")] public static TValue Is(Expression> match) { @@ -145,7 +165,6 @@ public static TValue Is(Expression> match) /// /// Allows the specification of a predicate to perform matching of method call arguments. /// - /// [EditorBrowsable(EditorBrowsableState.Advanced)] public static TValue Is(Expression> match) { @@ -163,7 +182,16 @@ public static TValue Is(Expression> match) /// The upper bound of the range. /// The kind of range. See . /// Type of the argument to check. - /// + /// + /// The following example shows how to expect a method call with an integer argument + /// within the 0..100 range. + /// + /// mock.Setup(x => x.HasInventory( + /// It.IsAny<string>(), + /// It.IsInRange(0, 100, Range.Inclusive))) + /// .Returns(false); + /// + /// public static TValue IsInRange(TValue from, TValue to, Range rangeKind) where TValue : IComparable { @@ -189,7 +217,18 @@ public static TValue IsInRange(TValue from, TValue to, Range rangeKind) /// /// The sequence of possible values. /// Type of the argument to check. - /// + /// + /// The following example shows how to expect a method call with an integer argument + /// with value from a list. + /// + /// var values = new List<int> { 1, 2, 3 }; + /// + /// mock.Setup(x => x.HasInventory( + /// It.IsAny<string>(), + /// It.IsIn(values))) + /// .Returns(false); + /// + /// public static TValue IsIn(IEnumerable items) { return Match.Create(value => items.Contains(value), () => It.IsIn(items)); @@ -200,7 +239,16 @@ public static TValue IsIn(IEnumerable items) /// /// The sequence of possible values. /// Type of the argument to check. - /// + /// + /// The following example shows how to expect a method call with an integer argument + /// with a value of 1, 2, or 3. + /// + /// mock.Setup(x => x.HasInventory( + /// It.IsAny<string>(), + /// It.IsIn(1, 2, 3))) + /// .Returns(false); + /// + /// public static TValue IsIn(params TValue[] items) { return Match.Create(value => items.Contains(value), () => It.IsIn(items)); @@ -211,7 +259,18 @@ public static TValue IsIn(params TValue[] items) /// /// The sequence of disallowed values. /// Type of the argument to check. - /// + /// + /// The following example shows how to expect a method call with an integer argument + /// with value not found from a list. + /// + /// var values = new List<int> { 1, 2, 3 }; + /// + /// mock.Setup(x => x.HasInventory( + /// It.IsAny<string>(), + /// It.IsNotIn(values))) + /// .Returns(false); + /// + /// public static TValue IsNotIn(IEnumerable items) { return Match.Create(value => !items.Contains(value), () => It.IsNotIn(items)); @@ -222,7 +281,16 @@ public static TValue IsNotIn(IEnumerable items) /// /// The sequence of disallowed values. /// Type of the argument to check. - /// + /// + /// The following example shows how to expect a method call with an integer argument + /// of any value except 1, 2, or 3. + /// + /// mock.Setup(x => x.HasInventory( + /// It.IsAny<string>(), + /// It.IsNotIn(1, 2, 3))) + /// .Returns(false); + /// + /// public static TValue IsNotIn(params TValue[] items) { return Match.Create(value => !items.Contains(value), () => It.IsNotIn(items)); @@ -232,7 +300,14 @@ public static TValue IsNotIn(params TValue[] items) /// Matches a string argument if it matches the given regular expression pattern. /// /// The pattern to use to match the string argument value. - /// + /// + /// The following example shows how to expect a call to a method where the string argument + /// matches the given regular expression: + /// + /// mock.Setup(x => x.Check(It.IsRegex("[a-z]+"))) + /// .Returns(1); + /// + /// public static string IsRegex(string regex) { Guard.NotNull(regex, nameof(regex)); @@ -249,7 +324,14 @@ public static string IsRegex(string regex) /// /// The pattern to use to match the string argument value. /// The options used to interpret the pattern. - /// + /// + /// The following example shows how to expect a call to a method where the string argument + /// matches the given regular expression, in a case insensitive way: + /// + /// mock.Setup(x => x.Check(It.IsRegex("[a-z]+", RegexOptions.IgnoreCase))) + /// .Returns(1); + /// + /// public static string IsRegex(string regex, RegexOptions options) { Guard.NotNull(regex, nameof(regex)); diff --git a/src/Moq/It.xdoc b/src/Moq/It.xdoc deleted file mode 100644 index 37c3aa1bd..000000000 --- a/src/Moq/It.xdoc +++ /dev/null @@ -1,109 +0,0 @@ - - - - - - // Throws an exception for a call to Remove with any string value. - mock.Setup(x => x.Remove(It.IsAny<string>())).Throws(new InvalidOperationException()); - - - - - - This example shows how to return the value 1 whenever the argument to the - Do method is an even number. - - mock.Setup(x => x.Do(It.Is<int>(i => i % 2 == 0))) - .Returns(1); - - This example shows how to throw an exception if the argument to the - method is a negative number: - - mock.Setup(x => x.GetUser(It.Is<int>(i => i < 0))) - .Throws(new ArgumentException()); - - - - - - The following example shows how to expect a method call - with an integer argument within the 0..100 range. - - mock.Setup(x => x.HasInventory( - It.IsAny<string>(), - It.IsInRange(0, 100, Range.Inclusive))) - .Returns(false); - - - - - - The following example shows how to expect a method call - with an integer argument with value from a list. - - var values = new List<int> { 1, 2, 3 }; - - mock.Setup(x => x.HasInventory( - It.IsAny<string>(), - It.IsIn(values))) - .Returns(false); - - - - - - The following example shows how to expect a method call - with an integer argument with a value of 1, 2, or 3. - - mock.Setup(x => x.HasInventory( - It.IsAny<string>(), - It.IsIn(1, 2, 3))) - .Returns(false); - - - - - - The following example shows how to expect a method call - with an integer argument with value not found from a list. - - var values = new List<int> { 1, 2, 3 }; - - mock.Setup(x => x.HasInventory( - It.IsAny<string>(), - It.IsNotIn(values))) - .Returns(false); - - - - - - The following example shows how to expect a method call - with an integer argument of any value except 1, 2, or 3. - - mock.Setup(x => x.HasInventory( - It.IsAny<string>(), - It.IsNotIn(1, 2, 3))) - .Returns(false); - - - - - - The following example shows how to expect a call to a method where the - string argument matches the given regular expression: - - mock.Setup(x => x.Check(It.IsRegex("[a-z]+"))).Returns(1); - - - - - - The following example shows how to expect a call to a method where the - string argument matches the given regular expression, in a case insensitive way: - - mock.Setup(x => x.Check(It.IsRegex("[a-z]+", RegexOptions.IgnoreCase))).Returns(1); - - - - diff --git a/src/Moq/Match.cs b/src/Moq/Match.cs index 61320951f..d982f95d2 100644 --- a/src/Moq/Match.cs +++ b/src/Moq/Match.cs @@ -20,7 +20,47 @@ namespace Moq /// Argument matching is used to determine whether a concrete invocation in the mock /// matches a given setup. This matching mechanism is fully extensible. /// - /// + /// + /// Creating a custom matcher is straightforward. You just need to create a method + /// that returns a value from a call to + /// with your matching condition and optional friendly render expression: + /// + /// public Order IsBigOrder() + /// { + /// return Match.Create<Order>( + /// o => o.GrandTotal >= 5000, + /// () => IsBigOrder()); // a friendly expression to render on failures + /// } + /// + /// This method can be used in any mock setup invocation: + /// + /// mock.Setup(m => m.Submit(IsBigOrder()) + /// .Throws<UnauthorizedAccessException>(); + /// + /// At runtime, Moq knows that the return value was a matcher and + /// evaluates your predicate with the actual value passed into your predicate. + /// + /// Another example might be a case where you want to match a lists of orders + /// that contains a particular one. You might create matcher like the following: + /// + /// + /// public static class Orders + /// { + /// public static IEnumerable<Order> Contains(Order order) + /// { + /// return Match.Create<IEnumerable<Order>>(orders => orders.Contains(order)); + /// } + /// } + /// + /// Now we can invoke this static method instead of an argument in an invocation: + /// + /// var order = new Order { ... }; + /// var mock = new Mock<IRepository<Order>>(); + /// + /// mock.Setup(x => x.Save(Orders.Contains(order))) + /// .Throws<ArgumentException>(); + /// + /// public abstract class Match : IMatcher { /// diff --git a/src/Moq/Match.xdoc b/src/Moq/Match.xdoc deleted file mode 100644 index 7ef744f6e..000000000 --- a/src/Moq/Match.xdoc +++ /dev/null @@ -1,47 +0,0 @@ - - - - - Creating a custom matcher is straightforward. You just need to create a method - that returns a value from a call to with - your matching condition and optional friendly render expression: - - public Order IsBigOrder() - { - return Match.Create<Order>( - o => o.GrandTotal >= 5000, - /* a friendly expression to render on failures */ - () => IsBigOrder()); - } - - This method can be used in any mock setup invocation: - - mock.Setup(m => m.Submit(IsBigOrder()).Throws<UnauthorizedAccessException>(); - - At runtime, Moq knows that the return value was a matcher and - evaluates your predicate with the actual value passed into your predicate. - - Another example might be a case where you want to match a lists of orders - that contains a particular one. You might create matcher like the following: - - - public static class Orders - { - public static IEnumerable<Order> Contains(Order order) - { - return Match.Create<IEnumerable<Order>>(orders => orders.Contains(order)); - } - } - - Now we can invoke this static method instead of an argument in an - invocation: - - var order = new Order { ... }; - var mock = new Mock<IRepository<Order>>(); - - mock.Setup(x => x.Save(Orders.Contains(order))) - .Throws<ArgumentException>(); - - - - diff --git a/src/Moq/Mock.Generic.cs b/src/Moq/Mock.Generic.cs index e22976538..9586ea26f 100644 --- a/src/Moq/Mock.Generic.cs +++ b/src/Moq/Mock.Generic.cs @@ -28,7 +28,48 @@ namespace Moq /// that can be passed to the constructor. /// /// - /// + /// + /// The following example shows establishing setups with specific values for method invocations: + /// + /// // Arrange + /// var order = new Order(TALISKER, 50); + /// var warehouse = new Mock<IWarehouse>(); + /// warehouse.Setup(w => w.HasInventory(TALISKER, 50)).Returns(true); + /// + /// // Act + /// order.Fill(warehouse.Object); + /// + /// // Assert + /// Assert.True(order.IsFilled); + /// + /// + /// + /// The following example shows how to use the class + /// to specify conditions for arguments instead of specific values: + /// + /// // Arrange + /// var order = new Order(TALISKER, 50); + /// var warehouse = new Mock<IWarehouse>(); + /// + /// // shows how to expect a value within a range: + /// warehouse.Setup(x => x.HasInventory( + /// It.IsAny<string>(), + /// It.IsInRange(0, 100, Range.Inclusive))) + /// .Returns(false); + /// + /// // shows how to throw for unexpected calls. + /// warehouse.Setup(x => x.Remove( + /// It.IsAny<string>(), + /// It.IsAny<int>())) + /// .Throws(new InvalidOperationException()); + /// + /// // Act + /// order.Fill(warehouse.Object); + /// + /// // Assert + /// Assert.False(order.IsFilled); + /// + /// public partial class Mock : Mock, IMock where T : class { private static Type[] inheritedInterfaces; @@ -78,7 +119,11 @@ internal Mock(bool skipInitialize) /// /// Initializes an instance of the mock with behavior. /// - /// + /// + /// + /// var mock = new Mock<IFormatProvider>(); + /// + /// [SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")] public Mock() : this(MockBehavior.Default) @@ -94,7 +139,11 @@ public Mock() /// The mock will try to find the best match constructor given the constructor arguments, /// and invoke that to initialize the instance.This applies only for classes, not interfaces. /// - /// + /// + /// + /// var mock = new Mock<MyProvider>(someArgument, 25); + /// + /// [SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")] public Mock(params object[] args) : this(MockBehavior.Default, args) @@ -105,7 +154,11 @@ public Mock(params object[] args) /// Initializes an instance of the mock with the specified behavior. /// /// Behavior of the mock. - /// + /// + /// + /// var mock = new Mock<IFormatProvider>(MockBehavior.Strict); + /// + /// [SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")] public Mock(MockBehavior behavior) : this(behavior, new object[0]) @@ -122,7 +175,6 @@ public Mock(MockBehavior behavior) /// The mock will try to find the best match constructor given the constructor arguments, /// and invoke that to initialize the instance. This applies only to classes, not interfaces. /// - /// [SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")] public Mock(MockBehavior behavior, params object[] args) { @@ -321,7 +373,12 @@ public override Switches Switches /// If more than one setup is specified for the same method or property, /// the latest one wins and is the one that will be executed. /// - /// + /// + /// + /// var mock = new Mock<IProcessor>(); + /// mock.Setup(x => x.Execute("ping")); + /// + /// [SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures", Justification = "By design")] public ISetup Setup(Expression> expression) { @@ -338,7 +395,12 @@ public ISetup Setup(Expression> expression) /// If more than one setup is specified for the same method or property, /// the latest one wins and is the one that will be executed. /// - /// + /// + /// + /// mock.Setup(x => x.HasInventory("Talisker", 50)) + /// .Returns(true); + /// + /// [SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures", Justification = "By design")] public ISetup Setup(Expression> expression) { @@ -355,7 +417,12 @@ public ISetup Setup(Expression> expression /// If more than one setup is set for the same property getter, /// the latest one wins and is the one that will be executed. /// - /// + /// + /// + /// mock.SetupGet(x => x.Suspended) + /// .Returns(true); + /// + /// [SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures", Justification = "By design")] public ISetupGetter SetupGet(Expression> expression) { @@ -375,7 +442,11 @@ public ISetupGetter SetupGet(Expression /// - /// + /// + /// + /// mock.SetupSet(x => x.Suspended = true); + /// + /// public ISetupSetter SetupSet(Action setterExpression) { Guard.NotNull(setterExpression, nameof(setterExpression)); @@ -393,7 +464,11 @@ public ISetupSetter SetupSet(Action setterExpression /// If more than one setup is set for the same property setter, /// the latest one wins and is the one that will be executed. /// - /// + /// + /// + /// mock.SetupSet(x => x.Suspended = true); + /// + /// public ISetup SetupSet(Action setterExpression) { Guard.NotNull(setterExpression, nameof(setterExpression)); @@ -411,7 +486,11 @@ public ISetup SetupSet(Action setterExpression) /// If more than one setup is set for the same event add, /// the latest one wins and is the one that will be executed. /// - /// + /// + /// + /// mock.SetupAdd(x => x.EventHandler += (s, e) => {}); + /// + /// public ISetup SetupAdd(Action addExpression) { Guard.NotNull(addExpression, nameof(addExpression)); @@ -423,14 +502,18 @@ public ISetup SetupAdd(Action addExpression) } /// - /// Specifies a setup on the mocked type for a call to an event 'remove. + /// Specifies a setup on the mocked type for a call to an event remove. /// /// Lambda expression that removes an event. /// /// If more than one setup is set for the same event remove, /// the latest one wins and is the one that will be executed. /// - /// + /// + /// + /// mock.SetupRemove(x => x.EventHandler -= (s, e) => {}); + /// + /// public ISetup SetupRemove(Action removeExpression) { Guard.NotNull(removeExpression, nameof(removeExpression)); @@ -450,7 +533,21 @@ public ISetup SetupRemove(Action removeExpression) /// /// Type of the property, inferred from the property expression (does not need to be specified). /// - /// + /// + /// If you have an interface with an int property Value, + /// you might stub it using the following straightforward call: + /// + /// var mock = new Mock<IHaveValue>(); + /// mock.SetupProperty(v => v.Value); + /// + /// After the SetupProperty call has been issued, setting and retrieving + /// the object value will behave as expected: + /// + /// IHaveValue v = mock.Object; + /// v.Value = 5; + /// Assert.Equal(5, v.Value); + /// + /// [SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures", Justification = "By design")] [SuppressMessage("Microsoft.Naming", "CA1716:IdentifiersShouldNotMatchKeywords", MessageId = "Property", Justification = "This sets properties, so it's appropriate.")] public Mock SetupProperty(Expression> property) @@ -469,7 +566,24 @@ public Mock SetupProperty(Expression> property) /// /// Type of the property, inferred from the property expression (does not need to be specified). /// - /// + /// + /// If you have an interface with an int property Value, + /// you might stub it using the following straightforward call: + /// + /// var mock = new Mock<IHaveValue>(); + /// mock.SetupProperty(v => v.Value, 5); + /// + /// After the SetupProperty call has been issued, setting and retrieving the object value + /// will behave as expected: + /// + /// IHaveValue v = mock.Object; + /// Assert.Equal(5, v.Value); // Initial value was stored + /// + /// // New value set which changes the initial value + /// v.Value = 6; + /// Assert.Equal(6, v.Value); + /// + /// [SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures", Justification = "By design")] [SuppressMessage("Microsoft.Naming", "CA1716:IdentifiersShouldNotMatchKeywords", MessageId = "Property", Justification = "We're setting up a property, so it's appropriate.")] public Mock SetupProperty(Expression> property, TProperty initialValue) @@ -552,7 +666,18 @@ public ISetupConditionResult When(Func condition) /// /// Expression to verify. /// The invocation was not performed on the mock. - /// + /// + /// This example assumes that the mock has been used, and later we want to verify + /// that a given invocation with specific parameters was performed: + /// + /// var mock = new Mock<IProcessor>(); + /// + /// ... // exercise mock + /// + /// // Will throw if the test code didn't call Execute with a "ping" string argument. + /// mock.Verify(proc => proc.Execute("ping")); + /// + /// [SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures", Justification = "By design")] public void Verify(Expression> expression) { @@ -597,7 +722,6 @@ public void Verify(Expression> expression, Func times) /// Expression to verify. /// Message to show if verification fails. /// The invocation was not performed on the mock. - /// [SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures", Justification = "By design")] public void Verify(Expression> expression, string failMessage) { @@ -645,7 +769,18 @@ public void Verify(Expression> expression, Func times, string f /// Expression to verify. /// Type of return value from the expression. /// The invocation was not performed on the mock. - /// + /// + /// This example assumes that the mock has been used, and later we want to verify + /// that a given invocation with specific parameters was performed: + /// + /// var mock = new Mock<IWarehouse>(); + /// + /// ... // exercise mock + /// + /// // Will throw if the test code didn't call HasInventory. + /// mock.Verify(warehouse => warehouse.HasInventory(TALISKER, 50)); + /// + /// [SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures", Justification = "By design")] public void Verify(Expression> expression) { @@ -692,7 +827,19 @@ public void Verify(Expression> expression, Func /// Message to show if verification fails. /// Type of return value from the expression. /// The invocation was not performed on the mock. - /// + /// + /// This example assumes that the mock has been used, and later we want to verify + /// that a given invocation with specific parameters was performed: + /// + /// var mock = new Mock<IWarehouse>(); + /// + /// ... // exercise mock + /// + /// // Will throw if the test code didn't call HasInventory. + /// mock.Verify(warehouse => warehouse.HasInventory(TALISKER, 50), + /// "When filling orders, inventory has to be checked"); + /// + /// [SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures", Justification = "By design")] public void Verify(Expression> expression, string failMessage) { @@ -724,7 +871,18 @@ public void Verify(Expression> expression, Times times /// Type of the property to verify. Typically omitted as it can be inferred from the expression's return type. /// /// The invocation was not performed on the mock. - /// + /// + /// This example assumes that the mock has been used, and later we want to verify + /// that a given property was retrieved from it: + /// + /// var mock = new Mock<IWarehouse>(); + /// + /// ... // exercise mock + /// + /// // Will throw if the test code didn't retrieve the IsClosed property. + /// mock.VerifyGet(warehouse => warehouse.IsClosed); + /// + /// [SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures", Justification = "By design")] public void VerifyGet(Expression> expression) { @@ -774,7 +932,6 @@ public void VerifyGet(Expression> expression, Func /// Type of the property to verify. Typically omitted as it can be inferred from the expression's return type. /// /// The invocation was not performed on the mock. - /// [SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures", Justification = "By design")] public void VerifyGet(Expression> expression, string failMessage) { @@ -822,7 +979,18 @@ public void VerifyGet(Expression> expression, Func /// /// Expression to verify. /// The invocation was not performed on the mock. - /// + /// + /// This example assumes that the mock has been used, and later we want to verify + /// that a given property was set on it: + /// + /// var mock = new Mock<IWarehouse>(); + /// + /// ... // exercise mock + /// + /// // Will throw if the test code didn't set the IsClosed property. + /// mock.VerifySet(warehouse => warehouse.IsClosed = true); + /// + /// public void VerifySet(Action setterExpression) { Guard.NotNull(setterExpression, nameof(setterExpression)); @@ -869,7 +1037,19 @@ public void VerifySet(Action setterExpression, Func times) /// Expression to verify. /// Message to show if verification fails. /// The invocation was not performed on the mock. - /// + /// + /// This example assumes that the mock has been used, and later we want to verify + /// that a given property was set on it: + /// + /// var mock = new Mock<IWarehouse>(); + /// + /// ... // exercise mock + /// + /// // Will throw if the test code didn't set the IsClosed property. + /// mock.VerifySet(warehouse => warehouse.IsClosed = true, + /// "Warehouse should always be closed after the action"); + /// + /// public void VerifySet(Action setterExpression, string failMessage) { Guard.NotNull(setterExpression, nameof(setterExpression)); @@ -917,7 +1097,18 @@ public void VerifySet(Action setterExpression, Func times, string fail /// /// Expression to verify. /// The invocation was not performed on the mock. - /// + /// + /// This example assumes that the mock has been used, and later we want to verify + /// that a given event handler was subscribed to an event: + /// + /// var mock = new Mock<IWarehouse>(); + /// + /// ... // exercise mock + /// + /// // Will throw if the test code didn't subscribe to the OnClosed event. + /// mock.VerifyAdd(warehouse => warehouse.OnClosed += It.IsAny<EventHandler>()); + /// + /// public void VerifyAdd(Action addExpression) { Guard.NotNull(addExpression, nameof(addExpression)); @@ -964,7 +1155,6 @@ public void VerifyAdd(Action addExpression, Func times) /// Expression to verify. /// Message to show if verification fails. /// The invocation was not performed on the mock. - /// public void VerifyAdd(Action addExpression, string failMessage) { Guard.NotNull(addExpression, nameof(addExpression)); @@ -1012,7 +1202,18 @@ public void VerifyAdd(Action addExpression, Func times, string failMes /// /// Expression to verify. /// The invocation was not performed on the mock. - /// + /// + /// This example assumes that the mock has been used, and later we want to verify + /// that a given event handler was removed from an event: + /// + /// var mock = new Mock<IWarehouse>(); + /// + /// ... // exercise mock + /// + /// // Will throw if the test code didn't unsubscribe from the OnClosed event. + /// mock.VerifyRemove(warehouse => warehouse.OnClose -= It.IsAny<EventHandler>()); + /// + /// public void VerifyRemove(Action removeExpression) { Guard.NotNull(removeExpression, nameof(removeExpression)); @@ -1059,7 +1260,6 @@ public void VerifyRemove(Action removeExpression, Func times) /// Expression to verify. /// Message to show if verification fails. /// The invocation was not performed on the mock. - /// public void VerifyRemove(Action removeExpression, string failMessage) { Guard.NotNull(removeExpression, nameof(removeExpression)); @@ -1122,7 +1322,32 @@ public void VerifyNoOtherCalls() /// The argument is invalid for the target event invocation, /// or the is not an event attach or detach expression. /// - /// + /// + /// The following example shows how to raise a + /// event: + /// + /// var mock = new Mock<IViewModel>(); + /// mock.Raise(x => x.PropertyChanged -= null, new PropertyChangedEventArgs("Name")); + /// + /// + /// + /// This example shows how to invoke an event with a custom event arguments class + /// in a view that will cause its corresponding presenter to react by changing its state: + /// + /// var mockView = new Mock<IOrdersView>(); + /// var presenter = new OrdersPresenter(mockView.Object); + /// + /// // Check that the presenter has no selection by default + /// Assert.Null(presenter.SelectedOrder); + /// + /// // Raise the event with a specific arguments data + /// mockView.Raise(v => v.SelectionChanged += null, new OrderEventArgs { Order = new Order("moq", 500) }); + /// + /// // Now the presenter reacted to the event, and we have a selected order + /// Assert.NotNull(presenter.SelectedOrder); + /// Assert.Equal("moq", presenter.SelectedOrder.ProductName); + /// + /// [SuppressMessage("Microsoft.Design", "CA1030:UseEventsWhereAppropriate", Justification = "Raises the event, rather than being one.")] public void Raise(Action eventExpression, EventArgs args) { @@ -1136,7 +1361,14 @@ public void Raise(Action eventExpression, EventArgs args) /// The arguments are invalid for the target event invocation, /// or the is not an event attach or detach expression. /// - /// + /// + /// The following example shows how to raise a custom event that does not adhere + /// to the standard EventHandler: + /// + /// var mock = new Mock<IViewModel>(); + /// mock.Raise(x => x.MyEvent -= null, "Name", bool, 25); + /// + /// [SuppressMessage("Microsoft.Design", "CA1030:UseEventsWhereAppropriate", Justification = "Raises the event, rather than being one.")] public void Raise(Action eventExpression, params object[] args) { diff --git a/src/Moq/Mock.Generic.xdoc b/src/Moq/Mock.Generic.xdoc deleted file mode 100644 index 8fafde120..000000000 --- a/src/Moq/Mock.Generic.xdoc +++ /dev/null @@ -1,362 +0,0 @@ - - - - - The following example shows establishing setups with specific values - for method invocations: - - // Arrange - var order = new Order(TALISKER, 50); - var mock = new Mock<IWarehouse>(); - - mock.Setup(x => x.HasInventory(TALISKER, 50)).Returns(true); - - // Act - order.Fill(mock.Object); - - // Assert - Assert.True(order.IsFilled); - - The following example shows how to use the class - to specify conditions for arguments instead of specific values: - - // Arrange - var order = new Order(TALISKER, 50); - var mock = new Mock<IWarehouse>(); - - // shows how to expect a value within a range - mock.Setup(x => x.HasInventory( - It.IsAny<string>(), - It.IsInRange(0, 100, Range.Inclusive))) - .Returns(false); - - // shows how to throw for unexpected calls. - mock.Setup(x => x.Remove( - It.IsAny<string>(), - It.IsAny<int>())) - .Throws(new InvalidOperationException()); - - // Act - order.Fill(mock.Object); - - // Assert - Assert.False(order.IsFilled); - - - - - - var mock = new Mock<IFormatProvider>(); - - - - - var mock = new Mock<MyProvider>(someArgument, 25); - - - - - var mock = new Mock<IFormatProvider>(MockBehavior.Relaxed); - - - - - var mock = new Mock<MyProvider>(someArgument, 25); - - - - - - var mock = new Mock<IProcessor>(); - mock.Setup(x => x.Execute("ping")); - - - - - - - mock.Setup(x => x.HasInventory("Talisker", 50)).Returns(true); - - - - - - - mock.SetupGet(x => x.Suspended) - .Returns(true); - - - - - - - mock.SetupSet(x => x.Suspended = true); - - - - - - - mock.SetupSet(x => x.Suspended = true); - - - - - - - mock.SetupAdd(x => x.EventHandler += (s, e) => {}); - - - - - - - mock.SetupRemove(x => x.EventHandler -= (s, e) => {}); - - - - - - If you have an interface with an int property Value, you might - stub it using the following straightforward call: - - var mock = new Mock<IHaveValue>(); - mock.Stub(v => v.Value); - - After the Stub call has been issued, setting and - retrieving the object value will behave as expected: - - IHaveValue v = mock.Object; - - v.Value = 5; - Assert.Equal(5, v.Value); - - - - - - If you have an interface with an int property Value, you might - stub it using the following straightforward call: - - var mock = new Mock<IHaveValue>(); - mock.SetupProperty(v => v.Value, 5); - - After the SetupProperty call has been issued, setting and - retrieving the object value will behave as expected: - - IHaveValue v = mock.Object; - // Initial value was stored - Assert.Equal(5, v.Value); - - // New value set which changes the initial value - v.Value = 6; - Assert.Equal(6, v.Value); - - - - - - This example assumes that the mock has been used, and later we want to verify that a given - invocation with specific parameters was performed: - - var mock = new Mock<IProcessor>(); - // exercise mock - //... - // Will throw if the test code didn't call Execute with a "ping" string argument. - mock.Verify(proc => proc.Execute("ping")); - - - - - - This example assumes that the mock has been used, and later we want to verify that a given - invocation with specific parameters was performed: - - var mock = new Mock<IProcessor>(); - // exercise mock - //... - // Will throw if the test code didn't call Execute with a "ping" string argument. - mock.Verify(proc => proc.Execute("ping")); - - - - - - This example assumes that the mock has been used, and later we want to verify that a given - invocation with specific parameters was performed: - - var mock = new Mock<IWarehouse>(); - // exercise mock - //... - // Will throw if the test code didn't call HasInventory. - mock.Verify(warehouse => warehouse.HasInventory(TALISKER, 50)); - - - - - - This example assumes that the mock has been used, - and later we want to verify that a given invocation - with specific parameters was performed: - - var mock = new Mock<IWarehouse>(); - // exercise mock - //... - // Will throw if the test code didn't call HasInventory. - mock.Verify(warehouse => warehouse.HasInventory(TALISKER, 50), "When filling orders, inventory has to be checked"); - - - - - - This example assumes that the mock has been used, - and later we want to verify that a given property - was retrieved from it: - - var mock = new Mock<IWarehouse>(); - // exercise mock - //... - // Will throw if the test code didn't retrieve the IsClosed property. - mock.VerifyGet(warehouse => warehouse.IsClosed); - - - - - - This example assumes that the mock has been used, - and later we want to verify that a given property - was retrieved from it: - - var mock = new Mock<IWarehouse>(); - // exercise mock - //... - // Will throw if the test code didn't retrieve the IsClosed property. - mock.VerifyGet(warehouse => warehouse.IsClosed); - - - - - - This example assumes that the mock has been used, - and later we want to verify that a given property - was set on it: - - var mock = new Mock<IWarehouse>(); - // exercise mock - //... - // Will throw if the test code didn't set the IsClosed property. - mock.VerifySet(warehouse => warehouse.IsClosed = true); - - - - - - This example assumes that the mock has been used, - and later we want to verify that a given property - was set on it: - - var mock = new Mock<IWarehouse>(); - // exercise mock - //... - // Will throw if the test code didn't set the IsClosed property. - mock.VerifySet(warehouse => warehouse.IsClosed = true, "Warehouse should always be closed after the action"); - - - - - - This example assumes that the mock has been used, - and later we want to verify that a given event - was added to it: - - var mock = new Mock<IWarehouse>(); - // exercise mock - //... - // Will throw if the test code didn't subscribe to the OnClosed event. - mock.VerifyAdd(warehouse => warehouse.OnClose += It.IsAny<EventHandler>()); - - - - - - This example assumes that the mock has been used, - and later we want to verify that a given event - was added to it: - - var mock = new Mock<IWarehouse>(); - // exercise mock - //... - // Will throw if the test code didn't subscribe to the OnClose event. - mock.VerifyAdd(warehouse => warehouse.OnClose += It.IsAny<EventHandler>(), "Warehouse should add an event"); - - - - - - This example assumes that the mock has been used, - and later we want to verify that a given event - was removed from it: - - var mock = new Mock<IWarehouse>(); - // exercise mock - //... - // Will throw if the test code didn't unsubscribe from the OnClosed event. - mock.VerifyRemove(warehouse => warehouse.OnClose -= It.IsAny<EventHandler>()); - - - - - - This example assumes that the mock has been used, - and later we want to verify that a given event - was removed from it: - - var mock = new Mock<IWarehouse>(); - // exercise mock - //... - // Will throw if the test code didn't unsubscribe from the OnClosed event. - mock.VerifyRemove(warehouse => warehouse.OnClose -= It.IsAny<EventHandler>(), "Warehouse should remove an event"); - - - - - - The following example shows how to raise a event: - - var mock = new Mock<IViewModel>(); - - mock.Raise(x => x.PropertyChanged -= null, new PropertyChangedEventArgs("Name")); - - - - This example shows how to invoke an event with a custom event arguments - class in a view that will cause its corresponding presenter to - react by changing its state: - - var mockView = new Mock<IOrdersView>(); - var presenter = new OrdersPresenter(mockView.Object); - - // Check that the presenter has no selection by default - Assert.Null(presenter.SelectedOrder); - - // Raise the event with a specific arguments data - mockView.Raise(v => v.SelectionChanged += null, new OrderEventArgs { Order = new Order("moq", 500) }); - - // Now the presenter reacted to the event, and we have a selected order - Assert.NotNull(presenter.SelectedOrder); - Assert.Equal("moq", presenter.SelectedOrder.ProductName); - - - - - - The following example shows how to raise a custom event that does not adhere to - the standard EventHandler: - - var mock = new Mock<IViewModel>(); - - mock.Raise(x => x.MyEvent -= null, "Name", bool, 25); - - - - diff --git a/src/Moq/Mock.cs b/src/Moq/Mock.cs index cc17b22fc..a1063f071 100644 --- a/src/Moq/Mock.cs +++ b/src/Moq/Mock.cs @@ -40,7 +40,22 @@ protected Mock() /// /// The mock associated with the mocked object. /// The received instance was not created by Moq. - /// + /// + /// The following example shows how to add a new setup to an object instance + /// which is not the original but rather the object associated with it: + /// + /// // Typed instance, not the mock, is retrieved from some test API. + /// HttpContextBase context = GetMockContext(); + /// + /// // context.Request is the typed object from the "real" API + /// // so in order to add a setup to it, we need to get + /// // the mock that "owns" it + /// Mock<HttpRequestBase> request = Mock.Get(context.Request); + /// + /// request.Setup(req => req.AppRelativeCurrentExecutionFilePath) + /// .Returns(tempUrl); + /// + /// public static Mock Get(T mocked) where T : class { if (mocked is IMocked mockedOfT) @@ -227,7 +242,22 @@ public DefaultValue DefaultValue /// Verifies that all verifiable expectations have been met. /// /// Not all verifiable expectations were met. - /// + /// + /// This example sets up an expectation and marks it as verifiable. + /// After the mock is used, a Verify() call is issued on the mock + /// to ensure the method in the setup was invoked: + /// + /// var mock = new Mock<IWarehouse>(); + /// this.Setup(x => x.HasInventory(TALISKER, 50)) + /// .Returns(true) + /// .Verifiable(); + /// + /// ... + /// + /// // Will throw if the test code did not call HasInventory. + /// this.Verify(); + /// + /// public void Verify() { var error = this.TryVerify(); @@ -241,7 +271,22 @@ public void Verify() /// Verifies all expectations regardless of whether they have been flagged as verifiable. /// /// At least one expectation was not met. - /// + /// + /// This example sets up an expectation without marking it as verifiable. + /// After the mock is used, a call is issued on the mock + /// to ensure that all expectations are met: + /// + /// var mock = new Mock<IWarehouse>(); + /// this.Setup(x => x.HasInventory(TALISKER, 50)) + /// .Returns(true); + /// + /// ... + /// + /// // Will throw if the test code did not call HasInventory, + /// // even though that expectation was not marked as verifiable. + /// mock.VerifyAll(); + /// + /// public void VerifyAll() { var error = this.TryVerifyAll(); @@ -686,7 +731,19 @@ internal static void RaiseEvent(Mock mock, LambdaExpression expression, Stack /// The mock type has already been generated by accessing the property. /// - /// + /// + /// The following example creates a mock for the main interface + /// and later adds to it to verify it's called by the consumer code: + /// + /// var mock = new Mock<IProcessor>(); + /// mock.Setup(x => x.Execute("ping")); + /// + /// // add IDisposable interface + /// var disposable = mock.As<IDisposable>(); + /// disposable.Setup(d => d.Dispose()) + /// .Verifiable(); + /// + /// [SuppressMessage("Microsoft.Naming", "CA1716:IdentifiersShouldNotMatchKeywords", MessageId = "As", Justification = "We want the method called exactly as the keyword because that's what it does, it adds an implemented interface so that you can cast it later.")] public virtual Mock As() where TInterface : class diff --git a/src/Moq/Mock.xdoc b/src/Moq/Mock.xdoc deleted file mode 100644 index 1ff5db31f..000000000 --- a/src/Moq/Mock.xdoc +++ /dev/null @@ -1,69 +0,0 @@ - - - - - The following example shows how to add a new setup to an object - instance which is not the original but rather - the object associated with it: - - // Typed instance, not the mock, is retrieved from some test API. - HttpContextBase context = GetMockContext(); - - // context.Request is the typed object from the "real" API - // so in order to add a setup to it, we need to get - // the mock that "owns" it - Mock<HttpRequestBase> request = Mock.Get(context.Request); - mock.Setup(req => req.AppRelativeCurrentExecutionFilePath) - .Returns(tempUrl); - - - - - - This example sets up an expectation and marks it as verifiable. After - the mock is used, a Verify() call is issued on the mock - to ensure the method in the setup was invoked: - - var mock = new Mock<IWarehouse>(); - this.Setup(x => x.HasInventory(TALISKER, 50)).Returns(true).Verifiable(); - ... - // other test code - ... - // Will throw if the test code did not call HasInventory. - this.Verify(); - - - - - - This example sets up an expectation without marking it as verifiable. After - the mock is used, a call is issued on the mock - to ensure that all expectations are met: - - var mock = new Mock<IWarehouse>(); - this.Setup(x => x.HasInventory(TALISKER, 50)).Returns(true); - ... - // other test code - ... - // Will throw if the test code did not call HasInventory, even - // though that expectation was not marked as verifiable. - this.VerifyAll(); - - - - - - The following example creates a mock for the main interface - and later adds to it to verify - it's called by the consumer code: - - var mock = new Mock<IProcessor>(); - mock.Setup(x => x.Execute("ping")); - - // add IDisposable interface - var disposable = mock.As<IDisposable>(); - disposable.Setup(d => d.Dispose()).Verifiable(); - - - - diff --git a/src/Moq/Moq.csproj b/src/Moq/Moq.csproj index be4e5cb24..8cfec0bff 100644 --- a/src/Moq/Moq.csproj +++ b/src/Moq/Moq.csproj @@ -97,23 +97,6 @@ IReturns.tt - - It.cs - - - - Match.cs - - - - Mock.Generic.cs - Designer - - - - Mock.cs - - TextTemplatingFileGenerator ReturnsExtensions.Generated.cs