diff --git a/Src/FluentAssertions/Common/ObjectExtensions.cs b/Src/FluentAssertions/Common/ObjectExtensions.cs
index 7ba5e3bdc..e1bf0f003 100644
--- a/Src/FluentAssertions/Common/ObjectExtensions.cs
+++ b/Src/FluentAssertions/Common/ObjectExtensions.cs
@@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.Globalization;
+using FluentAssertions.Formatting;
namespace FluentAssertions.Common;
@@ -77,4 +78,12 @@ ushort or
uint or
ulong);
}
+
+ ///
+ /// Convenience method to format an object to a string using the class.
+ ///
+ public static string ToFormattedString(this object source)
+ {
+ return Formatter.ToString(source);
+ }
}
diff --git a/Src/FluentAssertions/Execution/AssertionChain.cs b/Src/FluentAssertions/Execution/AssertionChain.cs
index ef72a3f6b..ce085dcfe 100644
--- a/Src/FluentAssertions/Execution/AssertionChain.cs
+++ b/Src/FluentAssertions/Execution/AssertionChain.cs
@@ -253,12 +253,23 @@ private Continuation FailWith(Func getFailureReason)
public void OverrideCallerIdentifier(Func getCallerIdentifier)
{
this.getCallerIdentifier = getCallerIdentifier;
+ HasOverriddenCallerIdentifier = true;
}
public AssertionChain WithCallerPostfix(string postfix)
{
var originalCallerIdentifier = getCallerIdentifier;
getCallerIdentifier = () => originalCallerIdentifier() + postfix;
+ HasOverriddenCallerIdentifier = true;
+
+ return this;
+ }
+
+ public AssertionChain WithCallerPrefix(string prefix)
+ {
+ var originalCallerIdentifier = getCallerIdentifier;
+ getCallerIdentifier = () => prefix + originalCallerIdentifier();
+ HasOverriddenCallerIdentifier = true;
return this;
}
@@ -305,4 +316,6 @@ public AssertionChain UsingLineBreaks
return this;
}
}
+
+ public bool HasOverriddenCallerIdentifier { get; private set; }
}
diff --git a/Src/FluentAssertions/Formatting/Formatter.cs b/Src/FluentAssertions/Formatting/Formatter.cs
index 93ba19030..4ac3f13bf 100644
--- a/Src/FluentAssertions/Formatting/Formatter.cs
+++ b/Src/FluentAssertions/Formatting/Formatter.cs
@@ -26,6 +26,7 @@ public static class Formatter
new XElementValueFormatter(),
new XAttributeValueFormatter(),
new PropertyInfoFormatter(),
+ new MethodInfoFormatter(),
new NullValueFormatter(),
new GuidValueFormatter(),
new DateTimeOffsetValueFormatter(),
diff --git a/Src/FluentAssertions/Formatting/MethodInfoFormatter.cs b/Src/FluentAssertions/Formatting/MethodInfoFormatter.cs
new file mode 100644
index 000000000..ad32c3199
--- /dev/null
+++ b/Src/FluentAssertions/Formatting/MethodInfoFormatter.cs
@@ -0,0 +1,31 @@
+using System.Reflection;
+
+namespace FluentAssertions.Formatting;
+
+public class MethodInfoFormatter : IValueFormatter
+{
+ ///
+ /// Indicates whether the current can handle the specified .
+ ///
+ /// The value for which to create a .
+ ///
+ /// if the current can handle the specified value; otherwise, .
+ ///
+ public bool CanHandle(object value)
+ {
+ return value is MethodInfo;
+ }
+
+ public void Format(object value, FormattedObjectGraph formattedGraph, FormattingContext context, FormatChild formatChild)
+ {
+ var method = (MethodInfo)value;
+ if (method is null)
+ {
+ formattedGraph.AddFragment("");
+ }
+ else
+ {
+ formattedGraph.AddFragment($"{method!.DeclaringType!.Name + "." + method.Name}");
+ }
+ }
+}
diff --git a/Src/FluentAssertions/Formatting/PropertyInfoFormatter.cs b/Src/FluentAssertions/Formatting/PropertyInfoFormatter.cs
index c9746c290..7ec15ed75 100644
--- a/Src/FluentAssertions/Formatting/PropertyInfoFormatter.cs
+++ b/Src/FluentAssertions/Formatting/PropertyInfoFormatter.cs
@@ -18,6 +18,17 @@ public bool CanHandle(object value)
public void Format(object value, FormattedObjectGraph formattedGraph, FormattingContext context, FormatChild formatChild)
{
- formattedGraph.AddFragment(((PropertyInfo)value).Name);
+ var property = (PropertyInfo)value;
+
+ if (property is null)
+ {
+ formattedGraph.AddFragment("");
+ }
+ else
+ {
+ var propTypeName = property.PropertyType.Name;
+
+ formattedGraph.AddFragment($"{propTypeName} {property.DeclaringType}.{property.Name}");
+ }
}
}
diff --git a/Src/FluentAssertions/Types/MethodBaseAssertions.cs b/Src/FluentAssertions/Types/MethodBaseAssertions.cs
index 7aaac75eb..3b7c995b5 100644
--- a/Src/FluentAssertions/Types/MethodBaseAssertions.cs
+++ b/Src/FluentAssertions/Types/MethodBaseAssertions.cs
@@ -47,17 +47,20 @@ public AndConstraint HaveAccessModifier(
assertionChain
.BecauseOf(because, becauseArgs)
.ForCondition(Subject is not null)
- .FailWith($"Expected method to be {accessModifier}{{reason}}, but {{context:member}} is .");
+ .FailWith($"Expected method to be {accessModifier}{{reason}}, but {{context:method}} is .");
if (assertionChain.Succeeded)
{
CSharpAccessModifier subjectAccessModifier = Subject.GetCSharpAccessModifier();
+ var subject = assertionChain.HasOverriddenCallerIdentifier
+ ? assertionChain.CallerIdentifier
+ : "method " + Subject.ToFormattedString();
+
assertionChain
.ForCondition(accessModifier == subjectAccessModifier)
.BecauseOf(because, becauseArgs)
- .FailWith(
- $"Expected method {Subject!.Name} to be {accessModifier}{{reason}}, but it is {subjectAccessModifier}.");
+ .FailWith($"Expected {subject} to be {accessModifier}{{reason}}, but it is {subjectAccessModifier}.");
}
return new AndConstraint((TAssertions)this);
@@ -90,10 +93,14 @@ public AndConstraint NotHaveAccessModifier(CSharpAccessModifier acc
{
CSharpAccessModifier subjectAccessModifier = Subject.GetCSharpAccessModifier();
+ var subject = assertionChain.HasOverriddenCallerIdentifier
+ ? assertionChain.CallerIdentifier
+ : "method " + Subject.ToFormattedString();
+
assertionChain
.ForCondition(accessModifier != subjectAccessModifier)
.BecauseOf(because, becauseArgs)
- .FailWith($"Expected method {Subject!.Name} not to be {accessModifier}{{reason}}, but it is.");
+ .FailWith($"Expected {subject} not to be {accessModifier}{{reason}}, but it is.");
}
return new AndConstraint((TAssertions)this);
diff --git a/Src/FluentAssertions/Types/PropertyInfoAssertions.cs b/Src/FluentAssertions/Types/PropertyInfoAssertions.cs
index a1beee41d..11d3b9b80 100644
--- a/Src/FluentAssertions/Types/PropertyInfoAssertions.cs
+++ b/Src/FluentAssertions/Types/PropertyInfoAssertions.cs
@@ -4,6 +4,7 @@
using System.Reflection;
using FluentAssertions.Common;
using FluentAssertions.Execution;
+using FluentAssertions.Formatting;
namespace FluentAssertions.Types;
@@ -44,7 +45,7 @@ public AndConstraint BeVirtual(
assertionChain
.ForCondition(Subject.IsVirtual())
.BecauseOf(because, becauseArgs)
- .FailWith($"Expected property {GetDescriptionFor(Subject)} to be virtual{{reason}}, but it is not.");
+ .FailWith("Expected property {0} to be virtual{{reason}}, but it is not.", Subject);
}
return new AndConstraint(this);
@@ -60,7 +61,8 @@ public AndConstraint BeVirtual(
///
/// Zero or more objects to format using the placeholders in .
///
- public AndConstraint NotBeVirtual([StringSyntax("CompositeFormat")] string because = "", params object[] becauseArgs)
+ public AndConstraint NotBeVirtual([StringSyntax("CompositeFormat")] string because = "",
+ params object[] becauseArgs)
{
assertionChain
.BecauseOf(because, becauseArgs)
@@ -72,7 +74,7 @@ public AndConstraint NotBeVirtual([StringSyntax("Composi
assertionChain
.ForCondition(!Subject.IsVirtual())
.BecauseOf(because, becauseArgs)
- .FailWith($"Expected property {GetDescriptionFor(Subject)} not to be virtual{{reason}}, but it is.");
+ .FailWith("Expected property {0} not to be virtual{{reason}}, but it is.", Subject);
}
return new AndConstraint(this);
@@ -130,21 +132,17 @@ public AndConstraint BeWritable(CSharpAccessModifier acc
assertionChain
.BecauseOf(because, becauseArgs)
.ForCondition(Subject is not null)
- .FailWith($"Expected {Identifier} to be {accessModifier}{{reason}}, but {{context:property}} is .");
+ .FailWith($"Expected {{context:property}} to be {accessModifier}{{reason}}, but it is .")
+ .Then
+ .ForCondition(Subject!.CanWrite)
+ .BecauseOf(because, becauseArgs)
+ .FailWith("Expected {0} to have a setter {{reason}}.", assertionChain.HasOverriddenCallerIdentifier ? assertionChain.CallerIdentifier : Subject);
if (assertionChain.Succeeded)
{
- assertionChain
- .ForCondition(Subject!.CanWrite)
- .BecauseOf(because, becauseArgs)
- .FailWith(
- "Expected {context:property} {0} to have a setter{reason}.",
- Subject);
-
- if (assertionChain.Succeeded)
- {
- Subject!.GetSetMethod(nonPublic: true).Should().HaveAccessModifier(accessModifier, because, becauseArgs);
- }
+ assertionChain.WithCallerPrefix("setter of ");
+ assertionChain.ReuseOnce();
+ Subject!.GetSetMethod(nonPublic: true).Should().HaveAccessModifier(accessModifier, because, becauseArgs);
}
return new AndConstraint(this);
@@ -166,17 +164,11 @@ public AndConstraint NotBeWritable(
assertionChain
.BecauseOf(because, becauseArgs)
.ForCondition(Subject is not null)
- .FailWith("Expected property not to have a setter{reason}, but {context:property} is .");
-
- if (assertionChain.Succeeded)
- {
- assertionChain
- .ForCondition(!Subject!.CanWrite)
- .BecauseOf(because, becauseArgs)
- .FailWith(
- "Expected {context:property} {0} not to have a setter{reason}.",
- Subject);
- }
+ .FailWith("Expected {context:property} not to have a setter{reason}, but it is .")
+ .Then
+ .ForCondition(!Subject!.CanWrite)
+ .BecauseOf(because, becauseArgs)
+ .FailWith("Expected {0} not to have a setter {{reason}}.", Subject);
return new AndConstraint(this);
}
@@ -191,7 +183,8 @@ public AndConstraint NotBeWritable(
///
/// Zero or more objects to format using the placeholders in .
///
- public AndConstraint BeReadable([StringSyntax("CompositeFormat")] string because = "", params object[] becauseArgs)
+ public AndConstraint BeReadable([StringSyntax("CompositeFormat")] string because = "",
+ params object[] becauseArgs)
{
assertionChain
.BecauseOf(because, becauseArgs)
@@ -202,7 +195,7 @@ public AndConstraint BeReadable([StringSyntax("Composite
{
assertionChain.ForCondition(Subject!.CanRead)
.BecauseOf(because, becauseArgs)
- .FailWith("Expected property " + Subject.Name + " to have a getter{reason}, but it does not.");
+ .FailWith("Expected property {0}, to have a getter{reason}, but it does not.", Subject);
}
return new AndConstraint(this);
@@ -229,18 +222,15 @@ public AndConstraint BeReadable(CSharpAccessModifier acc
assertionChain
.BecauseOf(because, becauseArgs)
.ForCondition(Subject is not null)
- .FailWith($"Expected {Identifier} to be {accessModifier}{{reason}}, but {{context:property}} is .");
+ .FailWith($"Expected {{context:property}} to be {accessModifier}{{reason}}, but it is .")
+ .Then
+ .ForCondition(Subject!.CanRead)
+ .BecauseOf(because, becauseArgs)
+ .FailWith("Expected {0} to have a getter {{reason}}, but it does not.", Subject);
if (assertionChain.Succeeded)
{
- assertionChain.ForCondition(Subject!.CanRead)
- .BecauseOf(because, becauseArgs)
- .FailWith("Expected property " + Subject.Name + " to have a getter{reason}, but it does not.");
-
- if (assertionChain.Succeeded)
- {
- Subject!.GetGetMethod(nonPublic: true).Should().HaveAccessModifier(accessModifier, because, becauseArgs);
- }
+ Subject!.GetGetMethod(nonPublic: true).Should().HaveAccessModifier(accessModifier, because, becauseArgs);
}
return new AndConstraint(this);
@@ -270,8 +260,7 @@ public AndConstraint NotBeReadable(
.ForCondition(!Subject!.CanRead)
.BecauseOf(because, becauseArgs)
.FailWith(
- "Expected {context:property} {0} not to have a getter{reason}.",
- Subject);
+ "Expected {0} not to have a getter {{reason}}.", Subject);
}
return new AndConstraint(this);
@@ -303,8 +292,8 @@ public AndConstraint Return(Type propertyType,
{
assertionChain.ForCondition(Subject!.PropertyType == propertyType)
.BecauseOf(because, becauseArgs)
- .FailWith("Expected Type of property " + Subject.Name + " to be {0}{reason}, but it is {1}.",
- propertyType, Subject.PropertyType);
+ .FailWith("Expected type of property {2} to be {0}{reason}, but it is {1}.",
+ propertyType, Subject.PropertyType, Subject);
}
return new AndConstraint(this);
@@ -321,7 +310,8 @@ public AndConstraint Return(Type propertyType,
///
/// Zero or more objects to format using the placeholders in .
///
- public AndConstraint Return([StringSyntax("CompositeFormat")] string because = "", params object[] becauseArgs)
+ public AndConstraint Return([StringSyntax("CompositeFormat")] string because = "",
+ params object[] becauseArgs)
{
return Return(typeof(TReturn), because, becauseArgs);
}
@@ -353,7 +343,7 @@ public AndConstraint NotReturn(Type propertyType,
assertionChain
.ForCondition(Subject!.PropertyType != propertyType)
.BecauseOf(because, becauseArgs)
- .FailWith("Expected Type of property " + Subject.Name + " not to be {0}{reason}, but it is.", propertyType);
+ .FailWith("Expected Type of property {1} not to be {0}{reason}, but it is.", propertyType, Subject);
}
return new AndConstraint(this);
@@ -370,24 +360,13 @@ public AndConstraint NotReturn(Type propertyType,
///
/// Zero or more objects to format using the placeholders in .
///
- public AndConstraint NotReturn([StringSyntax("CompositeFormat")] string because = "", params object[] becauseArgs)
+ public AndConstraint NotReturn([StringSyntax("CompositeFormat")] string because = "",
+ params object[] becauseArgs)
{
return NotReturn(typeof(TReturn), because, becauseArgs);
}
- internal static string GetDescriptionFor(PropertyInfo property)
- {
- if (property is null)
- {
- return string.Empty;
- }
-
- var propTypeName = property.PropertyType.Name;
-
- return $"{propTypeName} {property.DeclaringType}.{property.Name}";
- }
-
- internal override string SubjectDescription => GetDescriptionFor(Subject);
+ internal override string SubjectDescription => Formatter.ToString(Subject);
///
/// Returns the type of the subject the assertion applies on.
diff --git a/Src/FluentAssertions/Types/PropertyInfoSelectorAssertions.cs b/Src/FluentAssertions/Types/PropertyInfoSelectorAssertions.cs
index a4aa31bb5..4aca17468 100644
--- a/Src/FluentAssertions/Types/PropertyInfoSelectorAssertions.cs
+++ b/Src/FluentAssertions/Types/PropertyInfoSelectorAssertions.cs
@@ -6,6 +6,7 @@
using System.Reflection;
using FluentAssertions.Common;
using FluentAssertions.Execution;
+using FluentAssertions.Formatting;
namespace FluentAssertions.Types;
@@ -221,7 +222,7 @@ private PropertyInfo[] GetPropertiesWith()
private static string GetDescriptionsFor(IEnumerable properties)
{
- IEnumerable descriptions = properties.Select(property => PropertyInfoAssertions.GetDescriptionFor(property));
+ IEnumerable descriptions = properties.Select(property => Formatter.ToString(property));
return string.Join(Environment.NewLine, descriptions);
}
diff --git a/Src/FluentAssertions/Types/TypeAssertions.cs b/Src/FluentAssertions/Types/TypeAssertions.cs
index 0af347192..55cf26d97 100644
--- a/Src/FluentAssertions/Types/TypeAssertions.cs
+++ b/Src/FluentAssertions/Types/TypeAssertions.cs
@@ -269,7 +269,7 @@ public AndWhich BeDecoratedWith(
/// Zero or more objects to format using the placeholders in .
///
/// is .
- public AndWhichConstraint BeDecoratedWith(
+ public AndWhich BeDecoratedWith(
Expression> isMatchingAttributePredicate,
[StringSyntax("CompositeFormat")] string because = "", params object[] becauseArgs)
where TAttribute : Attribute
@@ -287,7 +287,7 @@ public AndWhichConstraint BeDecoratedWith(this, attributes);
+ return new AndWhich(this, attributes);
}
///
@@ -300,7 +300,7 @@ public AndWhichConstraint BeDecoratedWith
/// Zero or more objects to format using the placeholders in .
///
- public AndWhichConstraint BeDecoratedWithOrInherit(
+ public AndWhich BeDecoratedWithOrInherit(
[StringSyntax("CompositeFormat")] string because = "", params object[] becauseArgs)
where TAttribute : Attribute
{
@@ -312,7 +312,7 @@ public AndWhichConstraint BeDecoratedWithOrInherit(this, attributes);
+ return new AndWhich(this, attributes);
}
///
@@ -330,7 +330,7 @@ public AndWhichConstraint BeDecoratedWithOrInherit.
///
/// is .
- public AndWhichConstraint BeDecoratedWithOrInherit(
+ public AndWhich BeDecoratedWithOrInherit(
Expression> isMatchingAttributePredicate,
[StringSyntax("CompositeFormat")] string because = "", params object[] becauseArgs)
where TAttribute : Attribute
@@ -348,7 +348,7 @@ public AndWhichConstraint BeDecoratedWithOrInherit(this, attributes);
+ return new AndWhich(this, attributes);
}
///
@@ -889,7 +889,7 @@ public AndConstraint NotBeStatic([StringSyntax("CompositeFormat"
/// is .
/// is .
/// is empty.
- public AndWhichConstraint HaveProperty(
+ public AndWhich HaveProperty(
Type propertyType, string name,
[StringSyntax("CompositeFormat")] string because = "", params object[] becauseArgs)
{
@@ -907,7 +907,6 @@ public AndWhichConstraint HaveProperty(
if (assertionChain.Succeeded)
{
propertyInfo = Subject.FindPropertyByName(name);
- var propertyInfoDescription = PropertyInfoAssertions.GetDescriptionFor(propertyInfo);
assertionChain
.BecauseOf(because, becauseArgs)
@@ -915,10 +914,10 @@ public AndWhichConstraint HaveProperty(
.FailWith($"Expected {propertyType.Name} {Subject}.{name} to exist{{reason}}, but it does not.")
.Then
.ForCondition(propertyInfo.PropertyType == propertyType)
- .FailWith($"Expected {propertyInfoDescription} to be of type {propertyType}{{reason}}, but it is not.");
+ .FailWith($"Expected {0} to be of type {propertyType}{{reason}}, but it is not.", propertyInfo);
}
- return new AndWhichConstraint(this, propertyInfo);
+ return new AndWhich(this, propertyInfo);
}
///
@@ -936,7 +935,7 @@ public AndWhichConstraint HaveProperty(
///
/// is .
/// is empty.
- public AndWhichConstraint HaveProperty(
+ public AndWhich HaveProperty(
string name, [StringSyntax("CompositeFormat")] string because = "", params object[] becauseArgs)
{
return HaveProperty(typeof(TProperty), name, because, becauseArgs);
@@ -968,12 +967,11 @@ public AndConstraint NotHaveProperty(string name,
if (assertionChain.Succeeded)
{
PropertyInfo propertyInfo = Subject.FindPropertyByName(name);
- var propertyInfoDescription = PropertyInfoAssertions.GetDescriptionFor(propertyInfo);
assertionChain
.BecauseOf(because, becauseArgs)
.ForCondition(propertyInfo is null)
- .FailWith($"Expected {propertyInfoDescription} to not exist{{reason}}, but it does.");
+ .FailWith("Expected {0} to not exist{{reason}}, but it does.", propertyInfo);
}
return new AndConstraint(this);
@@ -1275,18 +1273,20 @@ public AndConstraint NotHaveExplicitMethod(
///
/// is .
/// is .
- public AndWhichConstraint HaveIndexer(
+ public AndWhich HaveIndexer(
Type indexerType, IEnumerable parameterTypes,
[StringSyntax("CompositeFormat")] string because = "", params object[] becauseArgs)
{
Guard.ThrowIfArgumentIsNull(indexerType);
Guard.ThrowIfArgumentIsNull(parameterTypes);
+ string parameterString = GetParameterString(parameterTypes);
+
assertionChain
.BecauseOf(because, becauseArgs)
.ForCondition(Subject is not null)
.FailWith(
- $"Expected {indexerType.Name} {{context:type}}[{GetParameterString(parameterTypes)}] to exist{{reason}}" +
+ $"Expected {indexerType.Name} {{context:type}}[{parameterString}] to exist{{reason}}" +
", but {context:type} is .");
PropertyInfo propertyInfo = null;
@@ -1294,20 +1294,20 @@ public AndWhichConstraint HaveIndexer(
if (assertionChain.Succeeded)
{
propertyInfo = Subject.GetIndexerByParameterTypes(parameterTypes);
- var propertyInfoDescription = PropertyInfoAssertions.GetDescriptionFor(propertyInfo);
assertionChain
.BecauseOf(because, becauseArgs)
.ForCondition(propertyInfo is not null)
.FailWith(
- $"Expected {indexerType.Name} {Subject}[{GetParameterString(parameterTypes)}] to exist{{reason}}" +
+ $"Expected {indexerType.Name} {Subject}[{parameterString}] to exist{{reason}}" +
", but it does not.")
.Then
.ForCondition(propertyInfo.PropertyType == indexerType)
- .FailWith($"Expected {propertyInfoDescription} to be of type {indexerType}{{reason}}, but it is not.");
+ .FailWith("Expected {0} to be of type {1}{reason}, but it is not.", propertyInfo, indexerType);
}
- return new AndWhichConstraint(this, propertyInfo);
+ return new AndWhich(this, propertyInfo, assertionChain,
+ $"[{parameterString}]");
}
///
diff --git a/Tests/FluentAssertions.Specs/Specialized/AssemblyAssertionSpecs.cs b/Tests/FluentAssertions.Specs/Specialized/AssemblyAssertionSpecs.cs
index 0bd236d7b..debf5e2c0 100644
--- a/Tests/FluentAssertions.Specs/Specialized/AssemblyAssertionSpecs.cs
+++ b/Tests/FluentAssertions.Specs/Specialized/AssemblyAssertionSpecs.cs
@@ -191,7 +191,8 @@ public void Can_continue_assertions_on_the_found_type()
.Which.Should().BeDecoratedWith();
// Assert
- act.Should().Throw().WithMessage("blah");
+ act.Should().Throw()
+ .WithMessage("Expected*WellKnownClassWithAttribute*decorated*SerializableAttribute*not found.");
}
[Fact]
diff --git a/Tests/FluentAssertions.Specs/Types/MethodBaseAssertionSpecs.cs b/Tests/FluentAssertions.Specs/Types/MethodBaseAssertionSpecs.cs
index 84a2bf8dc..997f09fb2 100644
--- a/Tests/FluentAssertions.Specs/Types/MethodBaseAssertionSpecs.cs
+++ b/Tests/FluentAssertions.Specs/Types/MethodBaseAssertionSpecs.cs
@@ -389,7 +389,7 @@ public void When_asserting_a_private_member_is_protected_it_throws_with_a_useful
// Assert
act.Should().Throw()
.WithMessage(
- "Expected method PrivateMethod to be Protected because we want to test the error message, but it is " +
+ "Expected method TestClass.PrivateMethod to be Protected because we want to test the error message, but it is " +
"Private.");
}
@@ -426,7 +426,7 @@ public void When_asserting_a_protected_member_is_public_it_throws_with_a_useful_
// Assert
act.Should().Throw()
.WithMessage(
- "Expected method set_ProtectedSetProperty to be Public because we want to test the error message, but it" +
+ "Expected method TestClass.set_ProtectedSetProperty to be Public because we want to test the error message, but it" +
" is Protected.");
}
@@ -463,7 +463,7 @@ public void When_asserting_a_public_member_is_internal_it_throws_with_a_useful_m
// Assert
act.Should().Throw()
.WithMessage(
- "Expected method get_PublicGetProperty to be Internal because we want to test the error message, but it" +
+ "Expected method TestClass.get_PublicGetProperty to be Internal because we want to test the error message, but it" +
" is Public.");
}
@@ -495,7 +495,7 @@ public void When_asserting_an_internal_member_is_protectedInternal_it_throws_wit
// Assert
act.Should().Throw()
.WithMessage(
- "Expected method InternalMethod to be ProtectedInternal because we want to test the error message, but" +
+ "Expected method TestClass.InternalMethod to be ProtectedInternal because we want to test the error message, but" +
" it is Internal.");
}
@@ -526,7 +526,7 @@ public void When_asserting_a_protected_internal_member_is_private_it_throws_with
// Assert
act.Should().Throw()
.WithMessage(
- "Expected method ProtectedInternalMethod to be Private because we want to test the error message, but it is " +
+ "Expected method TestClass.ProtectedInternalMethod to be Private because we want to test the error message, but it is " +
"ProtectedInternal.");
}
@@ -604,7 +604,7 @@ public void When_asserting_a_private_member_is_not_private_it_throws_with_a_usef
// Assert
act.Should().Throw()
- .WithMessage("Expected method PrivateMethod not to be Private*because we want to test the error message*");
+ .WithMessage("Expected method TestClass.PrivateMethod not to be Private*because we want to test the error message*");
}
[Fact]
@@ -638,7 +638,7 @@ public void When_asserting_a_protected_member_is_not_protected_it_throws_with_a_
// Assert
act.Should().Throw()
.WithMessage(
- "Expected method set_ProtectedSetProperty not to be Protected*because we want to test the error message*");
+ "Expected method TestClass.set_ProtectedSetProperty not to be Protected*because we want to test the error message*");
}
[Fact]
@@ -686,7 +686,7 @@ public void When_asserting_a_public_member_is_not_public_it_throws_with_a_useful
// Assert
act.Should().Throw()
- .WithMessage("Expected method get_PublicGetProperty not to be Public*because we want to test the error message*");
+ .WithMessage("Expected method TestClass.get_PublicGetProperty not to be Public*because we want to test the error message*");
}
[Fact]
@@ -716,7 +716,7 @@ public void When_asserting_an_internal_member_is_not_internal_it_throws_with_a_u
// Assert
act.Should().Throw()
- .WithMessage("Expected method InternalMethod not to be Internal*because we want to test the error message*");
+ .WithMessage("Expected method TestClass.InternalMethod not to be Internal*because we want to test the error message*");
}
[Fact]
@@ -747,7 +747,7 @@ public void When_asserting_a_protected_internal_member_is_not_protected_internal
// Assert
act.Should().Throw()
.WithMessage(
- "Expected method ProtectedInternalMethod not to be ProtectedInternal*because we want to test the error message*");
+ "Expected method TestClass.ProtectedInternalMethod not to be ProtectedInternal*because we want to test the error message*");
}
[Fact]
diff --git a/Tests/FluentAssertions.Specs/Types/PropertyInfoAssertionSpecs.cs b/Tests/FluentAssertions.Specs/Types/PropertyInfoAssertionSpecs.cs
index e4479a345..9ca993568 100644
--- a/Tests/FluentAssertions.Specs/Types/PropertyInfoAssertionSpecs.cs
+++ b/Tests/FluentAssertions.Specs/Types/PropertyInfoAssertionSpecs.cs
@@ -428,7 +428,7 @@ public void When_asserting_a_readwrite_property_is_not_writable_it_fails_with_us
action
.Should().Throw()
.WithMessage(
- "Expected propertyInfo ReadWriteProperty not to have a setter because we want to test the error message.");
+ "Expected ReadWriteProperty not to have a setter because we want to test the error message.");
}
[Fact]
@@ -444,7 +444,7 @@ public void When_asserting_a_writeonly_property_is_not_writable_it_fails_with_us
action
.Should().Throw()
.WithMessage(
- "Expected propertyInfo WriteOnlyProperty not to have a setter because we want to test the error message.");
+ "Expected WriteOnlyProperty not to have a setter because we want to test the error message.");
}
[Fact]
@@ -459,7 +459,7 @@ public void When_subject_is_null_not_be_writable_should_fail()
// Assert
act.Should().Throw()
- .WithMessage("Expected property not to have a setter *failure message*, but propertyInfo is .");
+ .WithMessage("Expected propertyInfo not to have a setter *failure message*, but it is .");
}
}
@@ -587,7 +587,7 @@ public void When_subject_is_null_be_readable_with_accessmodifier_should_fail()
// Assert
act.Should().Throw()
- .WithMessage("Expected property to be Public *failure message*, but propertyInfo is .");
+ .WithMessage("Expected propertyInfo to be Public *failure message*, but it is .");
}
[Fact]
@@ -652,7 +652,7 @@ public void Do_not_the_check_access_modifier_when_the_property_is_not_writable()
// Assert
action.Should().Throw()
- .WithMessage("Expected propertyInfo ReadOnlyProperty to have a setter.");
+ .WithMessage("Expected ReadOnlyProperty to have a setter.");
}
[Fact]
@@ -667,7 +667,7 @@ public void When_subject_is_null_be_writable_with_accessmodifier_should_fail()
// Assert
act.Should().Throw()
- .WithMessage("Expected property to be Public *failure message*, but propertyInfo is .");
+ .WithMessage("Expected propertyInfo to be Public *failure message*, but it is .");
}
[Fact]
diff --git a/Tests/FluentAssertions.Specs/Types/TypeAssertionSpecs.HaveIndexer.cs b/Tests/FluentAssertions.Specs/Types/TypeAssertionSpecs.HaveIndexer.cs
index 9f3bd5022..bf1b69182 100644
--- a/Tests/FluentAssertions.Specs/Types/TypeAssertionSpecs.HaveIndexer.cs
+++ b/Tests/FluentAssertions.Specs/Types/TypeAssertionSpecs.HaveIndexer.cs
@@ -23,7 +23,7 @@ public void When_asserting_a_type_has_an_indexer_which_it_does_then_it_succeeds(
type.Should()
.HaveIndexer(typeof(string), [typeof(string)])
.Which.Should()
- .BeWritable(CSharpAccessModifier.Internal)
+ .BeWritable(CSharpAccessModifier.Public)
.And.BeReadable(CSharpAccessModifier.Private);
// Assert
diff --git a/Tests/FluentAssertions.Specs/Types/TypeAssertionSpecs.HaveProperty.cs b/Tests/FluentAssertions.Specs/Types/TypeAssertionSpecs.HaveProperty.cs
index fe7f4cbb6..a7d96a9b0 100644
--- a/Tests/FluentAssertions.Specs/Types/TypeAssertionSpecs.HaveProperty.cs
+++ b/Tests/FluentAssertions.Specs/Types/TypeAssertionSpecs.HaveProperty.cs
@@ -30,6 +30,21 @@ public void When_asserting_a_type_has_a_property_which_it_does_then_it_succeeds(
act.Should().NotThrow();
}
+ [Fact]
+ public void The_name_of_the_property_is_passed_to_the_chained_assertion()
+ {
+ // Arrange
+ var type = typeof(ClassWithMembers);
+
+ // Act
+ Action act = () => type
+ .Should().HaveProperty(typeof(string), "PrivateWriteProtectedReadProperty")
+ .Which.Should().NotBeWritable();
+
+ // Assert
+ act.Should().Throw("Expected property PrivateWriteProtectedReadProperty not to have a setter.");
+ }
+
[Fact]
public void When_asserting_a_type_has_a_property_which_it_does_not_it_fails()
{