Skip to content

About

No description, website, or topics provided.

Resources

Contributing

Stars

11 stars

Watchers

1 watching

Forks

Latest commit

 

History

51 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Shouldly.FromAssert

NuGet License

Because life's too short for hard-to-read assertions! 🔍

What is this?

Shouldly.FromAssert is a Roslyn analyzer that helps you migrate from traditional NUnit assertions to the more human-readable Shouldly library. It's like having a friendly code review buddy who's really into making tests more readable (but doesn't drink your coffee).

Features

  • Automatically detects NUnit assertions and suggests Shouldly alternatives
  • Provides code fixes to transform assertions with a single click
  • Supports a wide range of assertion types:
    • Basic assertions (Assert.AreEqual → ShouldBe)
    • String assertions (StringAssert.Contains → ShouldContain)
    • Collection assertions (CollectionAssert.Contains → ShouldContain)
    • Type assertions (Assert.IsInstanceOf → ShouldBeOfType; Is.TypeOf<T>() → ShouldBeOfType<T>(), Is.InstanceOf<T>() → ShouldBeAssignableTo<T>(), with Is.Not and typeof(T) forms)
    • And many more!

Installation

dotnet add package Shouldly.FromAssert

Usage

  1. Install the package
  2. Write your tests as usual with NUnit
  3. Look for the analyzer suggestions (they'll appear as warnings)
  4. Click the lightbulb 💡 or press (Alt+Enter or Ctrl+. depending on the IDE religeon you practice)
  5. Select "Convert to Shouldly"
  6. Watch your assertions transform into beautiful, readable Shouldly statements

Before and After

// Before: 😕
Assert.That(contestant, Is.EqualTo(1337));
CollectionAssert.Contains(contestants, winner);
StringAssert.StartsWith("Hello", greeting);

// After: 😊
contestant.ShouldBe(1337);
contestants.ShouldContain(winner);
greeting.ShouldStartWith("Hello");

Supported Conversions

Here are some examples of the transformations this analyzer can perform:

NUnit Shouldly
Assert.That(x, Is.EqualTo(y)) x.ShouldBe(y)
Assert.IsTrue(x > 10) (x > 10).ShouldBeTrue()
Assert.IsNull(x) x.ShouldBeNull()
CollectionAssert.Contains(list, item) list.ShouldContain(item)
StringAssert.StartsWith("Hi", str) str.ShouldStartWith("Hi")
Assert.Throws<ArgumentException>(() => method()) Should.Throw<ArgumentException>(() => method())
Assert.Multiple(() => { Assert.That(a, Is.EqualTo(1)); Assert.IsNotNull(b); }) this.ShouldSatisfyAllConditions(() => a.ShouldBe(1), () => b.ShouldNotBeNull())
Assert.That(x, Is.EqualTo(y), "why") x.ShouldBe(y, "why")
Assert.That(x, Is.Null) x.ShouldBeNull()
Assert.That(list, Has.Count.EqualTo(3)) list.Count.ShouldBe(3)
Assert.That(list, Is.EquivalentTo(other)) list.ShouldBe(other, ignoreOrder: true)
Assert.That(s, Does.StartWith("/").And.EndWith(".png")) s.ShouldStartWith("/"); s.ShouldEndWith(".png");
Assert.That(x, Is.EqualTo(0.8).Within(0.001)) x.ShouldBe(0.8, 0.001)
Assert.ThrowsAsync<ArgumentException>(() => MethodAsync()) Should.Throw<ArgumentException>(() => MethodAsync())
Assert.Fail("why") throw new ShouldAssertException("why");
Assert.That(s, Does.Contain("a").Or.Contain("b")) new[] { "a", "b" }.ShouldContain(item => s.Contains(item))

And many more! Check out the tests for a complete list of supported conversions.

Assert.Multiple is only converted (and only reported) when its lambda contains nothing but expression statements and sits in an instance member, since ShouldSatisfyAllConditions needs this and takes one Action per condition. Hoist locals out of the block first. An async lambda in an async method has each awaited value moved into a local above the call (var readAsByteArray = await response.ReadAsByteArrayAsync();), unless an await is only evaluated conditionally (?., ??, &&, ||, ?:) or is a whole statement. With nullable enabled, a x!. on the first statement no longer carries into the later lambdas; add x.ShouldNotBeNull(); above the block instead. The asserts inside an Assert.Multiple are converted with it, so one fix-all (or one dotnet format analyzers --diagnostics SHU001 run) does the whole file.

Assert.Ignore, Assert.Pass, Assert.Inconclusive and Assert.Warn are runner control rather than assertions, so they aren't reported.

With nullable enabled, a Does.Contain, Does.StartWith, Does.EndWith or Does.Match on a string? that may be null becomes x.ShouldNotBeNull().ShouldContain(...). NUnit fails these on null, and Shouldly's string overloads take a non-nullable string, so the plain call would raise CS8604. Does.Not.Contain passes on null in NUnit, so it gets no ShouldNotBeNull().

Contributing

Found a bug? Have a suggestion? Want to add support for more assertions? We'd love your help! Please feel free to:

  1. Open an issue
  2. Submit a pull request
  3. Start a discussion
  4. Share your success stories

License

This project is licensed under the Apache License 2.0 - see the LICENSE file for details.

Acknowledgments

  • The awesome Shouldly team for making assertions more human
  • The Roslyn team for making this possible
  • Coffee ☕, for making developers possible

Made with 💚 by Agoda

About

No description, website, or topics provided.

Resources

Contributing

Stars

11 stars

Watchers

1 watching

Forks

Releases

Packages

Used by

Contributors

Languages