Skip to content

Best practices #585

@jnyrup

Description

@jnyrup

When I converted our test suite to Fluent Assertions I of course used the documentation a lot, but several times a had an assertion which it was not immediately clear to me how to convert.
So I think it would be nice (in addition to the documentation) to have a wiki or guidelines, i.e. tips on how to:

  • convert common assertions into fluent assertions
  • rewrite assertions to improve readability
  • rewrite of assertions to improve error messages (e.g CollectionAssertions instead of foreach + assertion)

I have made a list of many of the conversions I made.
Ideally those could be (wishful thinking) converted into an analyzer like https://github.com/xunit/xunit.analyzers

Assert.IsTrue(b) => b.Should().BeTrue();
Assert.IsFalse(b) => b.Should().BeFalse();
Assert.IsNull(o) => o.Should().BeNull()
Assert.IsNotNull(o) => o.Should().NotBeNull()
Assert.AreEqual(b, a) => a.Should().Be(b)
Assert.AreEqual(b, a, delta) => a.Should().BeApproximately(b, delta)
Assert.AreNotEqual(other, obj) => obj.Should().NotBe(other)
Assert.AreSame(other, obj) => obj.Should().BeSameAs(other)
Assert.AreNotSame(b, a) => a.Should().NotBeSameAs(b)
Assert.IsInstanceOfType(a, typeof(T)) => a.Should().BeOfType<T>()
Assert.IsNotInstanceOfType(a, typeof(T)) => a.Should().NotBeOfType<T>()
Assert.IsTrue(a == b) => a.Should().Be(b)
Assert.IsFalse(a == b) => a.Should().NotBe(b)
Assert.IsTrue(a != b) => a.Should().NotBe(b)
Assert.IsFalse(a != b) => a.Should().Be(b)
Assert.IsTrue(a > b) => a.Should().BeGreaterThan(b)
Assert.IsFalse(a > b) => a.Should().BeLessOrEqualTo(b)
Assert.IsTrue(a >= b) => a.Should().BeGreaterOrEqualTo(b)
Assert.IsFalse(a >= b) => a.Should().BeLessThan(b)
Assert.IsTrue(a < b) => a.Should().BeLessThan(b)
Assert.IsFalse(a < b) => a.Should().BeGreaterOrEqualTo(b)
Assert.IsTrue(a <= b) => a.Should().BeLessOrEqualTo(b)
Assert.IsFalse(a <= b) => a.Should().BeGreaterThan(b)

(lower <= num && num <= upper).Should().BeTrue() => num.Should().BeInRange(lower, upper)

num.Should().BeGreaterThan(0) => num.Should().BePositive()
num.Should().BeLessThan(0) => num.Should().BeNegative()

object.GetType().Should().Be(typeof(T)) => object.Should().BeOfType<T>()
object.GetType().Should().NotBe(typeof(T)) => object.Should().NotBeOfType<T>()
(object is T).Should().BeTrue() => object.Should().BeAssignableTo<T>()
(object as T).Should().NotBeNull() => object.Should().BeAssignableTo<T>()

(struct?).HasValue().Should().BeTrue() => (struct?).Should().HaveValue()
(struct?).HasValue().Should().BeFalse() => (struct?).Should().NotHaveValue()

enumerable.Any().Should().BeTrue() => enumerable.Should().NotBeEmpty()
enumerable.Any().Should().BeFalse() => enumerable.Should().BeEmpty()
enumerable.Any(e => e.Prop).Should().BeTrue() => enumerable.Should().Contain(e => e.Prop)
enumerable.Any(e => e.Prop).Should().BeFalse() => enumerable.Should().NotContain(e => e.Prop)
enumerable.All(e => e.Prop).Should().BeTrue() => enumerable.Should().OnlyContain(e => e.Prop) //fails on empty collection
enumerable.Contains(e).Should().BeTrue() => enumerable.Should().Contain(e)
enumerable.Contains(e).Should().BeFalse() => enumerable.Should().NotContain(e)
enumerable.Any(e).Should().BeFalse() => enumerable.Should().NotContain(e)
enumerable.Count().Should().Be(k) => enumerable.Should().HaveCount(k)
enumerable.Count().Should().BeGreaterThan(k) => enumerable.Should().HaveCount(e => e > k)
enumerable.Count().Should().BeGreaterOrEqualTo(k) => enumerable.Should().HaveCount(e => e >= k)
enumerable.Count().Should().BeLessThan(k) => enumerable.Should().HaveCount(e => e < k)
enumerable.Count().Should().BeLessOrEqualTo(k) => enumerable.Should().HaveCount(e => e <= k)
enumerable.Count().Should().HaveCount(1) => enumerable.Should().ContainSingle()
enumerable.Count().Should().HaveCount(0) => enumerable.Should().BeEmpty()
enumerable.Contains().Should().BeTrue() => enumerable.Should().Contain()
enumerable.Contains().Should().BeFalse() => enumerable.Should().NotContain()
enumerable.Where(e => e.Prop).Should().NotBeEmpty() => enumerable.Should().Contain(e => e.Prop)
enumerable.Where(e => e.Prop).Should().BeEmpty() => enumerable.Should().NotContain(e => e.Prop)
enumerable.Where(e => e.Prop).Should().HavingCount(1) => enumerable.Should().ContainSingle(e => e.Prop)
enumerable.Should().OnlyContain(e => !e.Prop) => enumerable.Should().NotContain(e => e.Prop)
enumerable.Should().NotBeNull().And.NotBeEmpty() => enumerable.Should().NotBeNullOrEmpty()
enumerable.ElementAt(k).Should().Be(element) => collection.Should().HaveElementAt(k, element)
enumerable.Skip(k).First().Should().Be(element) => enumerable.Should().HaveElementAt(k + 1, element)
enumerable.OrderBy(e => e.Prop).Should().Equal(enumerable) => enumerable.Should().BeInAscendingOrder(e => e.Prop)
enumerable.OrderByDescending(e => e.Prop).Should().Equal(enumerable) => enumerable.Should().BeInDescendingOrder(e => e.Prop)
enumerable1.Select(e1 => e1.Prop).Equal(enumerable2.Select(e2 => e2.Prop)) => enumerable1.Should().Equal(enumerable2, (e1, e2) => e1.Prop == e2.Prop)
enumerable1.Intersect(enumerable2).Should().BeEmpty() => enumerable1.Should().NotIntersectWith(enumerable2)
enumerable1.Intersect(enumerable2).Should().NotBeEmpty() => enumerable1.Should().IntersectWith(enumerable2)
enumerable.Select(e => e.Prop).Should().NotContainNulls() => enumerable.Select(e).Should().NotContain(e => e.Prop == null) //maybe?

list[k].Should().Be(element) => collection.Should().HaveElementAt(k, element)

dictionary.ContainsKey(key).Should().BeTrue() => dictionary.Should().ContainKey(key)
dictionary.ContainsKey(key).Should().BeFalse() => dictionary.Should().NotContainKey(key)
dictionary.ContainsValue(value).Should().BeTrue() => dictionary.Should().ContainValue(value)
dictionary.ContainsValue(value).Should().BeFalse() => dictionary.Should().NotContainValue(value)
dictionary.Should().ContainKey(key).And.ContainValue(value) => dictionary.Should().Contain(key, value)
dictionary.Should().ContainKey(KeyValuePair.Key).And.ContainValue(KeyValuePair.value) => dictionary.Should().Contain(KeyValuePair)

CollectionAssert.AllItemsAreUnique(collection) => collection.Should().OnlyHaveUniqueItems()
CollectionAssert.AreEqual(otherCollection, collection) => collection.Should().Equal(otherCollection)
CollectionAssert.AreNotEqual(otherCollection, collection) => collection.Should().NotEqual(otherCollection)
CollectionAssert.AreEquivalent(otherCollection, collection) => collection.Should().BeEquivalentTo(otherCollection)
CollectionAssert.AreNotEquivalent(otherCollection, collection) => collection.Should().NotBeEquivalentTo(otherCollection)
CollectionAssert.Contains(collection, element) => collection.Should().Contain(element)
CollectionAssert.DoesNotContain(collection, element) => collection.Should().NotContain(element)
CollectionAssert.IsSubsetOf(subset, superset) => subset.Should().BeSubset(superset)
CollectionAssert.IsNotSubsetOf(subset, superset) => subset.Should().NotBeSubset(superset)
CollectionAssert.AllItemsAreNotNull(collection) => collection.Should().NotContainNulls()
CollectionAssert.AllItemsAreInstancesOfType(collection, typeof(T)) => collection.ContainItemsAssignableTo<T>()

str.StartsWith(prefix).Should().BeTrue() => str.Should().StartWith(prefix)
str.EndsWith(suffix).Should().BeTrue() => str.Should().EndWith(suffix)
str.Should().NotBeNull().And.NotBeEmpty() => str.Should().NotBeNullOrEmpty()
string.NullOrEmpty(str).Should().BeTrue() => str.Should().BeNullOrEmpty()
string.NullOrEmpty(str).Should().BeFalse() => str.Should().NotBeNullOrEmpty()
string.NullOrWhiteSpace(str).Should().BeTrue() => str.Should().BeNullOrWhiteSpace()
string.NullOrWhiteSpace(str).Should().BeFalse() => str.Should().NotBeNullOrWhiteSpace()
str.Should().HaveCount(k) => str.Should().HaveLength(k)

StringAssert.Contains(str, substr) => str.Should().Contain(substr)
StringAssert.StartWith(str, prefix) => str.Should().StartWith(prefix)
StringAssert.EndsWith(str, suffix) => str.Should().EndWith(suffix)
StringAssert.Matches(str, pattern) => str.Should().MatchRegex(pattern)
StringAssert.DoesNotMatch(str, pattern) => str.Should().NotMatchRegex(pattern)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions