Showing posts with label NFluent. Show all posts
Showing posts with label NFluent. Show all posts

Monday, June 9, 2014

[Visual C# - Unit Tests] How to extend NFluent and make it even more powerful

 

In my last article on NFluent I have shown you how it can help you to easily write clear and meaningful unit tests. In this article I am going to explain how you can extent NFluent by adding new custom validations.

What are DataAnnotations and how to use them ?

The System.ComponentModel.DataAnnotations namespace allows to define constraints on classes, methods and properties. DataAnnotations are often used within application based on ASP.NET MVC and Entity Framework for validation purposes.

The example below shows how to constrain user objects, with the following rules : All user objects have mandatory ID and Name properties, while the value of the ID property has to be in-between 1 and 999 and the Name property cannot exceed 30 characters.

image

DataAnnotations are widely used within the .NET Framework and I am happy to announce that NFluent uses them for extending its functionalities. So nothing new to learn for developers, who are already using them in their daily work!

Extend NFluent by adding new custom validations

It is very easy to add new custom validations to NFluent, you just have write an extension method and add the new custom verification code, as you can see in the following example implementation :

image

Note that a FluentCheckException is returned in case of validation errors.

How to use the custom validation in your code

Now that you have added your custom validation code, you can use it within your unit tests. You just have to call the DataAnnotationsAreValid() method :

image

Conclusion

This article has shown how easy it is to extent NFluent by adding custom validation code and then using it within your unit tests by just doing a single method call. There are obviously other ways to extend NFluent, but this simple and quick example is already sufficient for most scenarios.


Share/Save/Bookmark

Wednesday, May 28, 2014

[C# - Unit Tests] NFluent : A tool to write much clearer Unit Tests !

NFluent is an Assertion library (http://www.n-fluent.net), which can be used in conjunction with all the common Unit Test Frameworks on the market (NUnit, MSTest, xUnit, …). It greatly simplifies the writing of good Unit Tests, which are clear and easy to understand, meaning also that they can be debugged more easily and efficiently.

image

It is common knowledge that writing good unit tests with good granularity and good coverage is a pre-requisite for high quality code – and in the end high quality applications. But even though most of the developers know that they should write them, there are barriers and developers do not like at all to do this task. Let us understand why that is the case and how NFluent can help us to overcome this problem !

Here is an example of a very simple Unit Test using the MSTest Framework :

image

The writing of Unit Tests is not very intuitive and natural. If you have applied naming conventions to your classes and methods (which you should always do !!) this might help you a little bit. But in general Unit Tests by themselves are not really self-explaining. In more complex contexts, developers have to understand in detail how the underlying classes and methods work to understand what has been tested and why it has been tested like this.

What if there were a way of writing your Unit Tests so that you can easily understand them in one line, without the need to check back in your class and method definition ? It would be great ? Well that is where NFluent comes into play !

NFluent is using a natural syntax to ease Unit Test development

Let us rewrite the last example using the NFluent syntax :

image

The most important line here is : Check.That<int>(result).IsEqualTo(4);

To understand what has been tested you just have to read the line, as you would do when reading a book ! The test is going to “Check that result (of type int) is equal to 4”. No ambiguity is possible, the test is directly human readable.

Let us see how easy it can get to understand when applying the NFluent syntax, so do you understand what the following tests are doing ?

  • Check.That<Calculator>(calculator).IsInstanceOf<Calculator>();
  • Check.That(value).IsPositive().And.Not.IsGreaterThan(80);
  • Check.That(numbers).IsOnlyMadeOf(1, 2, 3).And.HasSize(10);
  • Check.That(() => { throw new Exception("message"); }).Throws<Exception>().WithMessage("message");

That was easy right ? Try to identify the difference between these two tests :

  • Check.That<User>(user1).IsEqualTo<User>(user2); 
  • Check.That<User>(user1).HasFieldsWithSameValues(user2);

This is also very easy to do : the first test is comparing objects references while the second is comparing all the properties of the two user instances.

Clear error messages if checks fail

So what happens if checks fail when using NFluent? You get very meaningful and clear error messages, which help you understand why a test has failed. You may then modify your code very quickly to assure that it provides the expected behavior.

Here are some examples of failed unit test, see for yourself if you understand why they have failed :

  • The checked enumerable has 9 elements instead of 10.
  • The checked enumerable: [1, 2, 3]
  • The checked value is greater than the threshold.
  • The checked value: [100]
  • The expected value: less than [10]
  • The checked enumerable does not contain exactly the expected value(s).
  • The checked enumerable: ["A", "B", "C"] (3 items)
  • The expected value(s): ["A", "B", "C"] (3 items)

Conclusion

NFluent is a great asset when building Unit Tests. Using it will enhance your productivity and make your tests human readable. This is especially important when applying TDD approaches and/or Agile methodologies, where the testing code might become some sort of documentation.

There are still some possibilities of amelioration though. When checking your testing code the first error will stop the processing at the moment, which might slow down productivity. It would be better to recover a list of all detected violations to be able to fix them later in a single step.

If you chain your tests like this, the first violation will stop the processing :

image

If you want to play with NFluent or see how it has been implemented you can access its GIT repository. You may use NuGet to include it into your projects. It is available under an open-source license, so please try t for yourself and let me know what you think !


Share/Save/Bookmark