Should FluentAssertions be used in production code

2019-08-02 14:05发布

问题:

I've been using FluentAssertions for unit testing and was wondering why it's only ever mentioned in that context. If you generally write fail-fast production code with guards you would have to duplicate some of the functionality FluentAssertions already provides. Some of the reasons I can think of to not use it:

  1. Its focus is to be readable, not to perform well. Counter: isn't that what higher-level languages also do and related to the warning to not do premature optimization?
  2. Also related to performance, there is no good way to have some assertions not run when code is compiled in release mode. Counter: You may remove an assertion you think won't happen in production but leads to an exception that is hard to track down. As long as they're not affecting performance significantly, leave it.
  3. Its assertions don't always throw standard exceptions. For example, ArgumentNullException and ArgumentException are ubiquitous and expected, but FluentAssertions doesn't know you're testing an argument and throws a generic exception.

Maybe it's already known performance is significantly impacted so #1 and #2 are legitimate, but you would generally also want fast unit tests so the same logic could apply there. Any other good reasons not to use FluentAssertions in production code?

回答1:

Fluent Assertions is only mentioned for unit testing and other types of tests, as test code and production should be separated. E.g. when you use Fluent Assertions, you should not be forced to depend on the test dependencies of Fluent Assertions.

I cannot answer if Fluent Assertions is slow, the question is if it is too slow and that depends on the scenario. For unit tests its overhead is far covered by readability and improved failure messages. Using Fluent Assertions inside a hot loop could easily kill your performance. Again that depends on which function from Fluent Assertions is used. E.g. BeEquivalentTo heavily relies on reflection.

Debug.Assert serves another but related purpose. It asserts the state of your code, e.g. to check invariants.