Struggling for Competence

NUnit Assert.That examples

A few years ago we changed from using NUnits classic model of asserts, like Assert.AreEqual, to using the constraint model of asserts, which always begin with Assert.That. The functionality provided by both models is identical, but the Assert.That style tends to read better. So for example you write:


    // Constraint model of assert using Assert.That
    Assert.That(newspaper.Name, Is.EqualTo("The Times"));

Instead of


    // Classic model of assert using Assert.AreEqual
    Assert.AreEqual("The Times", newspaper.Name);

In the Assert.That style the constraint begins with a particular start word, for example "Is". Once you have the start word, you can usually guess the rest of what you want to write using intellisense. The start words are:

NUnit 3 Constraint Start Words
Constraint Start Word
Is
Has
Does
Contains
Throws
What follows are examples of the more tricky and obscure assertion cases:

Strings

    
        var sentence = "The good, the bad and the ugly";

        Assert.That(sentence, Is.Not.Null.And.Not.Empty);
        Assert.That(sentence, Is.EqualTo("The good, the bad and the ugly"));

        Assert.That(sentence, Does.StartWith("The good"));
        Assert.That(sentence, Does.Contain("the bad"));
        Assert.That(sentence, Does.EndWith("The ugly").IgnoreCase);

        // A second method of testing substring
        Assert.That(sentence, Contains.Substring("the bad"));
    

Exceptions

    
        var newspaper = new Newspaper();

        // Assert that exception not thrown
        Assert.That(() => newspaper.Download("Bobby"), Throws.Nothing);

        // Assert that exception is thrown
        Assert.That(() => newspaper.Download("Rupert"), Throws.Exception.TypeOf<ArgumentException>()
                                                              .With.Message.EqualTo("You need a subscription to download the newspaper"));
        // Shorter constraints for common exception types
        Assert.That(() => newspaper.Download("Rupert"), Throws.ArgumentException);
        // Inner exceptions
        Assert.That(() => newspaper.Download("Rupert"), Throws.ArgumentException.And.InnerException.Message.EqualTo("User not found")
                                                                                .And.InnerException.TypeOf<InvalidOperationException>());
    

DateTime

    
        // DateTime and Timespan Assertions can contain a tolerance
        Assert.That(newspaper.PublicationDate, Is.EqualTo(DateTime.UtcNow).Within(1).Seconds);
    

Collections

    
        var numbers = new List<int>(){ 2, 4, 6, 8 };

        // Equality => element by element equality
        Assert.That(numbers, Is.EqualTo(new []{ 2, 4, 6, 8 }));

        // Equivalence => same elements, but can be in a different order
        Assert.That(numbers, Is.EquivalentTo(new []{ 8, 6, 4, 2 }));

        // Counts
        Assert.That(numbers.Count, Is.EqualTo(4));
        Assert.That(numbers, Has.Count.EqualTo(4));

        // Empty collection
        Assert.That(new List<int>(), Is.Empty);
    

More Collections

    
        var newspapers = new List<Newspaper> { new Newspaper(){Name = "The Times", IsTabloid = false}, new Newspaper(){Name = "The Sun", IsTabloid = true}, new Newspaper(){Name = "The Mirror", IsTabloid = true }};

        // Has can be followed by a "counting" constraint
        // Matches allows you to write a lambda for the constraint
        Assert.That(newspapers, Has.Some.Matches<Newspaper>(n => n.Name.Contains("s")));
        Assert.That(newspapers, Has.One.Matches<Newspaper>(n => n.IsTabloid == false));
        Assert.That(newspapers, Has.Exactly(2).Matches<Newspaper>(n => n.IsTabloid));
        Assert.That(newspapers, Has.All.Matches<Newspaper>(n => n.Name.StartsWith("The")));
        Assert.That(newspapers, Has.None.Matches<Newspaper>(n => n.Name == "The Post"));
    

If you want you can download the code NUnitAssertThatExamples.cs