Quantcast
Channel: Fluent Assertions
Viewing all 1402 articles
Browse latest View live

New Post: Floating point precision


Created Issue: Please update documentation how to use extension methods to add custom verifications [10513]

$
0
0
In the documentation, there is Verification.Fail("Expected whatever..."); used to fail the test. I assume that is is now done with Execute.Verification or Execute.Fail.
Could you please update the docu.


Thanks
Urs

Updated Wiki: Documentation

$
0
0

Supported Test Frameworks

Fluent Assertions supports MSTest, NUnit and XUnit. Starting with version 1.3.0, you can simply add a reference to the corresponding test framework assembly to the unit test project. Fluent Assertions will automatically find the corresponding assembly and use it for throwing the framework-specific exceptions. If, for some unknown reason, Fluent Assertions fails to find the assembly, try specifying the framework explicitly using a configuration setting in the project’s app.config.

<configuration>    
  <appSettings>    
    <!-- Supported values: nunit, xunit and mstest -->
    <add key="FluentAssertions.TestFramework" value="nunit"/>
  </appSettings>
</configuration>

Reference Types

object theObject = null;
theObject.Should().BeNull("because the value is null");
     
theObject = "whatever";
theObject.Should().BeOfType<String>("because a {0} is set", typeof(String));
theObject.Should().NotBeNull();

string otherObject = "whatever";
theObject.Should().Be(otherObject, "because they have the same values");
     
theObject = otherObject;     
theObject.Should().BeSameAs(otherObject);
theObject.Should().NotBeSameAs(otherObject);

var ex = new ArgumentException();
ex.Should().BeAssignableTo<Exception>("because it is an exception");

var dummy = new Object();
dummy.Should().Match(d => (d.ToString() == "System.Object"));
dummy.Should().Match<string>(d => (d == "System.Object"));
dummy.Should().Match((string d) => (d == "System.Object"));

Some users requested the ability to easily downcast an object to one of its derived classes in a fluent way.

customer.Animals.First().As<Human>().Height.Should().Be(178);

Booleans

bool theBoolean = false;
theBoolean.Should().BeFalse("it's set to false");

theBoolean = true;
theBoolean.Should().BeTrue();
theBoolean.Should().Be(otherBoolean);

Strings

string theString = "";
theString.Should().BeEmpty();
theString.Should().NotBeEmpty("because the string is not empty"); 
theString.Should().HaveLength(0);

theString = "This is a String";
theString.Should().NotBeNull();
theString.Should().Be("This is a String");
theString.Should().NotBe("This is another String");
theString.Should().BeEquivalentTo("THIS IS A STRING");
theString.Should().EndWith("a String");
theString.Should().EndWithEquivalent("a string");
theString.Should().Contain("is a");
theString.Should().StartWith("This");
theString.Should().StartWithEquivalent("this");

string theString = null;
theString.Should().BeNull();

Integers, singles, doubles, decimals and everything else that implements IComparable

int theInt = 5;
theInt.Should().BeGreaterOrEqualTo(5);
theInt.Should().BeGreaterOrEqualTo(3);
theInt.Should().BeGreaterThan(4);     
theInt.Should().BeLessOrEqualTo(5);
theInt.Should().BeLessThan(6);
theInt.Should().BePositive();
theInt.Should().Be(5);
theInt.Should().NotBe(10);
theInt.Should().BeInRange(1,10); theInt = -8; theInt.Should().BeNegative(); double theDouble = 5.1; theDouble.Should().BeGreaterThan(5);
byte theByte = 2;
theByte.Should().Be(2);

short? theShort = null;
theShort.Should().NotHaveValue();

int? theInt = 3;
theInt.Should().HaveValue();

Notice that Should().Be() and Should().NotBe() are not available for floats and doubles. As explained in this article, floating point variables are inheritably inaccurate and should never be compared for equality. Instead, either use the Should().BeInRange() method or the following method specifically designed for floating point variables.

float value = 3.1415927F;
value.Should().BeApproximately(3.14F, 0.001F);

This will verify that the value of the float is between 3.139 and 3.141.

Dates, times and time spans

var theDatetime = new Datetime(2010, 3, 1, 22, 15, 0);

theDatetime.Should().BeAfter(new Datetime(2010, 2, 1));
theDatetime.Should().BeBefore(new Datetime(2010, 3, 2));     
theDatetime.Should().BeOnOrAfter(new Datetime(2010, 3, 1));

theDatetime.Should().Be(new Datetime(2010, 3, 1, 22, 15, 0));

theDatetime.Should().HaveDay(1);
theDatetime.Should().HaveMonth(3);
theDatetime.Should().HaveYear(2010);
theDatetime.Should().HaveHour(22);
theDatetime.Should().HaveMinute(15);
theDatetime.Should().HaveSecond(0);

In version 1.2 I've added a whole set of methods for asserting that the difference between two DateTime objects match a certain time frame. All five methods support a Before and After extension method. With version 1.4, you no longer have to use the TimeSpan class directly and instead use extension methods to convert a number to a TimeSpan.

theDatetime.Should().BeLessThan(10.Minutes()).Before(otherDatetime); // Equivalent to <
theDatetime.Should().BeWithin(2.Hours()).After(otherDatetime);       // Equivalent to <=
theDatetime.Should().BeMoreThan(1.Days()).Before(deadline);          // Equivalent to >
theDatetime.Should().BeAtLeast(2.Days()).Before(deliveryDate);       // Equivalent to >=
theDatetime.Should().BeExactly(24.Hours()).Before(appointement);     // Equivalent to ==

Version 1.4 introduces dedicated methods that apply to TimeSpans directly:

var timespan = new Timespan(12, 59, 59); 
timespan.Should().BePositive(); 
timespan.Should().BeNegative(); 
timespan.Should().Be(12.Hours()); 
timespan.Should().NotBe(1.Days()); 
timespan.Should().BeLessThan(someOtherTimespan); 
timespan.Should().BeLessOrEqual(someOtherTimespan); 
timespan.Should().BeGreaterThan(someOtherTimespan); 
timespan.Should().BeGreaterOrEqual(someOtherTimespan);

Collections

IEnumerable collection = new[] { 1, 2, 5, 8 };

collection.Should().NotBeEmpty()
     .And.HaveCount(4)
     .And.ContainInOrder(new[] { 2, 5 })
     .And.ContainItemsAssignableTto<int>();

collection.Should().Equal(new list<int> { 1, 2, 5, 8 });
collection.Should().Equal(1, 2, 5, 8);
collection.Should().BeEquivalent(8, 2, 1, 5);
collection.Should().NotBeEquivalent(8, 2, 3, 5);


collection.Should().HaveCount(c => c > 3).And.OnlyHaveUniqueItems();
collection.Should().HaveSameCount(new[] {6, 2, 0, 5});

collection.Should().BeSubsetOf(new[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, });
collection.Should().Contain(8).And.HaveElementAt(2, 5).And.NotBeSubsetOf(new[] {11, 56});
collection.Should().Contain(x => x > 3);
collection.Should().Contain(collection, 5, 6); // It should contain the original items, plus 5 and 6. collection.Should().OnlyContain(x => x < 10); collection.Should().OnlyContainItemsOfType<int>(); collection.Should().NotContain(82); collection.Should().NotContainNulls();
collection.Should().NotContain(x => x > 10); collection = new int[0]; collection.Should().BeEmpty();

Exceptions

The following example verifies that the Foo() method throws an InvalidOperationException which Message property has a specific value.

subject.Invoking(y => y.Foo("Hello"))
     .ShouldThrow<InvalidOperationException>()
     .WithMessage("Hello is not allowed at this moment”);

But if you, like me, prefer the arrange-act-assert syntax, you can also use an action in your act part.

Action act = () => subject.Foo2("Hello");
Act.ShouldThrow<InvalidOperationException>() .WithInnerException<ArgumentException>() .WithInnerMessage("whatever");

Notice that the example also verifies that the exception has a particular inner exception with a specific message. in fact, you can even check the individual properties of the exception instance using the And property.

Action act = () => subject.Foo(null));
act.ShouldThrow<ArgumentNullException>() .And.ParamName.Should().Equal("message");

An alternative syntax for doing the same is by chaining or more calls to the Where() method introduced in version 1.4.0:

Action act = () => subject.Foo(null));

act.ShouldThrow<ArgumentNullException>().Where(e => e.Message.StartsWith(“did”));

If the method you are testing returns an IEnumerable or IEnumerable<T> and it uses the yield keyword to construct that collection, just calling the method will not cause the effect you expected. Because the real work is not done until you actually iterate over that collection. you can use the Enumerating() extension method to force enumerating the collection like this.

Func<IEnumerable<char>> func = () => obj.SomeMethodThatUsesYield("blah");
func.Enumerating().ShouldThrow<ArgumentException>();

You do have to use the Func<T> type instead of Action<T> then.

On the other hand, you may want to verify that no exceptions were thrown.

Action act = () => subject.Foo("Hello"));
act.ShouldNotThrow();

I know that a unit test will fail anyhow if an exception was thrown, but this syntax returns a clearer description of the exception that was thrown and fits better to the AAA syntax.

If you want to verify that a specific exception is not thrown, and want to ignore others, you can do that using an overload:

Action act = () => subject.Foo("Hello"));
act.ShouldNotThrow<InvalidOperationException>();

Property Comparison

You can assert the equality of entire objects by comparing their properties by name. This even works if the types of the properties differ but a built-in conversion exists (through the Convert class). As an example, consider a Customer entity from some arbitrary domain model and its DTO counterpart CustomerDto. You can assert that the DTO has the same values as the entity using this syntax:

dto.ShouldHave().AllProperties().EqualTo(customer);

As long as all properties of dto are also available on customer, and their value is equal or convertible, the assertion succeeds. You can, however, exclude a specific property using a property expression, such as for instance the ID property:

dto.ShouldHave().AllPropertiesBut(d => d.Id).EqualTo(customer);

Which is equivalent to:

dto.ShouldHave().AllProperties().But(d => d.Id).EqualTo(customer);

The other way around is also possible. So if you only want to include two specific properties, use this syntax.

dto.ShouldHave().Properties(d => d.Name, d => d.Address).EqualTo(customer);

And finally, if you only want to compare the properties that both objects have, you can use the SharedProperties() method like this:

dto.ShouldHave().SharedProperties().EqualTo(customer);

Obviously, you can chain that with a But() method to exclude some of the shared properties.

Event Monitoring

Version 1.3.0 introduces a new set of extensions that allow you to verify that an object raised a particular event. Before you can invoke the assertion extensions, you must first tell Fluent Assertions that you want to monitor the object:

var subject = new EditCustomerViewModel();
subject.MonitorEvents();

Assuming that we’re dealing with a MVVM implementation, you might want to verify that it raised its PropertyChanged event for a particular property:

subject
  .ShouldRaise("PropertyChanged")
.WithSender(subject) .WithArgs<PropertyChangedEventArgs>(args => args.PropertyName == "SomeProperty");

Notice that WithSender() verifies that all occurrences had its sender argument set to the specified object. WithArgs() just verifies that at least one occurrence had a matching EventArgs object. In other words, event monitoring only works for events that comply with the standard two-argument sender/args .NET pattern.

Since verifying for PropertyChanged events is so common, I’ve included a specialized shortcut to the example above:

subject.ShouldRaisePropertyChangeFor(x => x.SomeProperty);

In version 1.4 you can also do the opposite; asserting that a particular event was not raised.

subject.ShouldNotRaisePropertyChangeFor(x => x.SomeProperty);

Or, if your project is .NET 3.5 or 4.0 based:

subject.ShouldNotRaise(“SomeOtherEvent”);

Important Limitation: Due to limitations in Silverlight, only the ShouldRaisePropertyChangeFor() and ShouldNotRaisePropertyChangeFor() methods are supported in the Silverlight version of Fluent Assertions.

Execution Time

New in version 1.4 is a method to assert that the execution time of particular method or action does not exceed a predefined value. To verify the execution time of a method, use the following syntax:

var subject = new SomePotentiallyVerySlowClass();
subject.ExecutionTimeOf(s => s.ExpensiveMethod()).ShouldNotExceed(500.Milliseconds());

Alternatively, to verify the execution time of an arbitrary action, use this syntax:

Action someAction = () => Thread.Sleep(510);
someAction.ExecutionTime().ShouldNotExceed(100.Milliseconds());

Since it doesn’t make sense to do something like that in Silverlight, it is only available in the .NET 3.5 and .NET 4.0 versions of Fluent Assertions.

Extensibility

Adding your own assertion extensions is quite straightforward and happens in my projects quite often. You have a few options though.

  • Extend one of the built-in classes such as CollectionAssertions<T>or ReferenceTypeAssertions<T> and expose them through a custom static class with extension methods named Should().
  • Create extension methods that extend an assertion class:
public static void BeWhatever<T>(this GenericCollectionAssertions<T> assertions, string reason, params object[] reasonArgs)
{ 
    Execute.Verification
.ForCondition(somecondition)
.BecauseOf(reason, reasonArgs)
.FailWith("Expected object not to be {1}{0}", null); }
  • Create a custom assertions class and use the Verification class to verify conditions and create comprehensive failure messages using the built-in formatters.

Commented Issue: Please update documentation how to use extension methods to add custom verifications [10513]

$
0
0
In the documentation, there is Verification.Fail("Expected whatever..."); used to fail the test. I assume that is is now done with Execute.Verification or Execute.Fail.
Could you please update the docu.


Thanks
Urs
Comments: ** Comment from web user: dennisdoomen **

Done.

New Post: Initial Setup

$
0
0

Just for those like me that started to use Fluent Assertions. Add the reference to Fluent Assertions  in your test project and add "using FluentAssertions;" at the top of your test file

New Post: Initial Setup

$
0
0

...in case you're not using an advanced tool like ReSharper or DevExpress :-)

Updated Wiki: Temporary Post Used For Theme Detection (4739ccba-c7dd-4774-aa36-f3d2bd86b782 - 3bfe001a-32de-4114-a6b4-4005b770f6d7)

$
0
0

This is a temporary post that was not deleted. Please delete this manually. (15ce7833-df31-4055-8ee5-eae2f0b8f366 - 3bfe001a-32de-4114-a6b4-4005b770f6d7)

Updated Wiki: Home

$
0
0

Project Description

Fluent Assertions is a set of .NET extension methods that allow you to more naturally specify the expected outcome of a TDD or BDD-style test. We currently use it in all our internal and client projects, and it is even used in the NCQRS project.

Why another framework?

We primarily use Visual Studio 2010’s own testing framework and were not satisfied by other similar frameworks. The best one we ran into missed a nice natural way for specifying the reason that is displayed when an assertion failed. Moreover, we like to be able to easily add domain-specific assertions without having to subclass a whole bunch of obscure interfaces and abstract classes. In the beginning of 2010, after having used the framework internally for almost a year, we decided to make it public and rebrand it as Fluent Assertions.

Example

// Verifying that a string begins, ends and contains a particular phrase.
string actual = "ABCDEFGHI";
actual.Should().StartWith("AB").And.EndWith("HI").And.Contain("EF").And.HaveLength(9);

// Verifying that the collection contains a specified number of elements
// and that all elements match a predicate.
IEnumerable collection = new[] { 1, 2, 3 }; collection.Should().HaveCount(4, "because we thought we put three items in the collection"))
collection.Should().Contain(i => i > 0); // Verifying that a particular business rule is enforced using exceptions. var recipe = new RecipeBuilder() .With(new IngredientBuilder().For("Milk").WithQuantity(200, Unit.Milliliters)) .Build(); Action action = () => recipe.AddIngredient("Milk", 100, Unit.Spoon); action .ShouldThrow<RuleViolationException>() .WithMessage("Cannot change the unit of an existing ingredient") .And.Violations.Should().Contain(BusinessRule.CannotChangeIngredientQuanity);
The nice thing about the second failing example is that it will throw an exception with the message

"Expected <4> items because we thought we put three items in the collection, but found <3>."

This should keep you from having to start the debugger to figure out what went wrong. This is one of the fundamental principles we think Fluent Assertions should help you with. Note that you don't need to include the word because explicitly. The framework will prepend your phrase with it automatically.

News

February 27th, 2011
Another update with lots of community requests. Read more about it over here.
 
January 15th, 2011
You can now download the latest version directly from within Visual Studio by using the NuGet package manager.
 
January 1st, 2011
Fluent Assertions 1.3.0 has been released with many improvements, event monitoring extensions and strong naming. More importantly, it is no longer linked to a particular version of NUnit, XUnit or MSTest.
 
August 27th, 2010
Fluent Assertions 1.2.3 has been released. It's another small release with some minor additions and bug fixes.  
 
June 29th, 2010
Fluent Assertions 1.2.2 has been released. It's a small release to fix some issues. Read more about it here

May 12th, 2010
Small release to fix an issue with enumerables that use the yield keyword. Now includes separate assemblies for different unit testing frameworks, including NUnit 2.5.5.10112.

April 12th, 2010
Fluent Assertions 1.2 has been released. Read more about it here

March 5th, 2010
We've worked hard to add some important missing features that we really needed, and also improve resilience against illegal arguments such as an empty collection or null. You can find it here: Fluent Assertions release 1.1.

Who are we?

We are a bunch of developers working for Aviva Solutions who highly value software quality, in particular

Source code checked in, #65015

Closed Issue: Better readability with extension methods on int [10087]

$
0
0
Include Minutes(), Hours() and Days() extension methods on integers, for better readability of DateTime assertions.
For example:

public static TimeSpan Minutes(this int source)
{
return TimeSpan.FromMinutes(source);
}

This allows assertions like:

theDateTime.Should().BeLessThan(10.Minutes().Before(otherDateTime));
Comments: Resolved with changeset 65015.

Source code checked in, #65033

$
0
0
Changed the version number to 1.4.0.1

New Post: myString.Should().Contain("abc") ignoring case

$
0
0

Hi!

What would be the best syntax to check for string containing another string ignoring case?

I see a couple of options:

   myString.Should().Contain("abc", StringComparison.OrdinalIgnoreCase);

or

   myString.Should().ContainIgnoreCase("abc");

First seems more generic but second is shorter, more intellisense-friendly and reads better.

We could have both, second just being just a shortcut for the first.

What do you think?

New Post: The name BeEquivalentTo() is misleading for strings

$
0
0

Hi!

The name of string assertion BeEquivalentTo looks misleading to me.

For collection assertions it means "contains same elements regardless of order".

For strings equivalence means case-insensitive comparison.

But if you consider string as a collection of characters then these definitions contradict each other.

Also the name should give clear understanding of what the method does without looking at intellisense (for example when browsing source code of some project via web browser).

Better name would be something like BeIgnoreCase or BeIgnoringCase or BeRegardlessCase or BeAnyCase or BeInAnyCase or are there even better options?

New Post: Method proposal: str.Should().BeBlank()

$
0
0

Hi!

I find quite useful to check that string is/is not blank (i.e. null, empty or whitespace-only).

Out of 800+ tests in my current project 18 use NotBeBlank and 3 use BeBlank.

I think it would be a good addition to FluentAssertions.

New Post: Method proposal: str.Should().BeBlank()

$
0
0

Don't you think it will be confusing to have a BeEmpty (count of chars == 0) and BeBlank()?

Additionaly, I do think an empty string is something different than a null-string. In my projects, returning null for a string is never allowed, just like returning null for a collection. BeEmpty throws (with a clear explanation) if your string is null. The only exception for this if you explicitly need to handle an uninitalized state (e.g. for lazy-initialization purposes).

Maybe, BeBlank() should do the same as BeEmpty() but still allow a whitespace-only string.


New Post: The name BeEquivalentTo() is misleading for strings

$
0
0

I agree with your statement that names of members should give a clear understanding. However, I never consider a string to be a collection of characters.

I don't want to introduce breaking changes, but I will think if a can come up with a better fluent name.

You know that you can simply extend FA, don't you?

New Post: myString.Should().Contain("abc") ignoring case

$
0
0

Continuing the 'equivalence' convention, I would say:

myString.Should().ContainEquivalentOf("abc");

New Post: myString.Should().NotContain("a")

Closed Feature: Resolve name of event in ShouldRaise using lambda expression [10233]

$
0
0
It would be more helpfull if the name of an event that should be raised could be deteremined using a lambda expression. Like: theClass.ShouldRaise(() => c.Event); This makes it easier for refactoring and prevents the risk of failing unittests because of a typo.

Created Feature: Add myString.Should().NotContain() and myString.Should().NotContainEquivalentOf() [10739]

Viewing all 1402 articles
Browse latest View live


<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>