Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Is there a possibility to control the checked values? #326

Open
dnperfors opened this issue May 2, 2020 · 3 comments
Open

Is there a possibility to control the checked values? #326

dnperfors opened this issue May 2, 2020 · 3 comments
Assignees
Labels

Comments

@dnperfors
Copy link

Expected Behavior

I am writing some custom checks where I would like to have more control over the checked values. This might be benifitial for the ContainsKey checks as well, so I use that as an example.

When I write the following check:

var dictionary = new Dictionary<string, string>
{
    ["Key1"] = "Value1",
    ["Key2"] = "Value2",
};

Check.That(dictionary).ContainsKey("MyKey");

I want to have the following message:

The checked dictionary does not contain the expected key.
    The checked dictionary keys:
    	{Key1, Key2} (2 items)
    Expected key:
    	["MyKey"]

Current Behavior

Currently I get the following error message:

The checked dictionary does not contain the expected key.
    The checked dictionary:
    	{[Key1, Value1], [Key2, Value2]} (2 items)
    Expected key:
    	["MyKey"]

Possible Solution

For the expected value I can already use the method DefineExpectedResult.
Would it be possible to get a DefineCheckedValues, or a way to add a formatter for the checked value?

Context

As said, I am writing some custom checks. These checks are around the HttpResponseMessage where I want to check for specific header names, but I don't want to show the value of the header. However, in other tests I do want to show the header value, but now I only see "{[Header, System.String[]]} (1 item)"

Your Environment

  • Version used: 2.7.0
  • Framework version: Net Standard 2.0
@dupdob
Copy link
Collaborator

dupdob commented May 22, 2020

Hello
have you tried using CheckSutAttribute [see wiki]?(https://github.com/tpierrain/NFluent/wiki/advanced-checks#checksutattribute).
This could help you get closer to what you are trying to achieve.

@dupdob dupdob self-assigned this May 22, 2020
@dnperfors
Copy link
Author

That is indeed what I ended up doing, however it forced me to re-implement the checks and I couldn't use some extension methods I have to check that specific the specific key is actually in there.

So instead of saying:

.FailWhen(sut => !sut.ContainsKey(expectedKey), "Key not found.")
.DefineCheckedValues(sut => sut.Select(x => x.Key))

I had to do:

.CheckSutAttributes(sut => sut.Select(x => x.Key).ToArray(), "keys")
.FailWhen(sut => !sut.Any(x => x == expectedKey), "Key not found.")

The advantage of the first version is that you can expand the check to also check the values, which is not as easy as the second version.

@dupdob
Copy link
Collaborator

dupdob commented May 23, 2020

Thanks for your input. I am still considering how to properly address this. I must say I have yet to come with a more convenient solution.
The current behaviour is intentional: it ensures a consistent reporting of the sut disregarding of the used check.
Rationale: a failing check is the signal of some expectations on production code not being met, but one can rarely identify why the expectation was not met. So NFluent aims at providing as much information as possible regarding the sut.
But when we can provide some focus or extra information which could help, the best way is add it to the initial error message.

Based on your example, you can achieve this with Analyze (see wiki) which gives you the maximum freedom:

 .Analyze((sut, context) =>
  {
    if (!sut.ContainsKey(x))
    {
      context.Fails($"Key {x} not found. Existing keys:{string.Join(',', sut.Select( t => t.Key))}.");
    }
    if (sut[x] != xValue)
    {
       context.Fails("The entry does not have the expected value: {sut[x]} instead of {xValue}."):
    } 
  }).EndCheck();

What do you think?
Note: I have not tested this code, so there may be bugs, but this is the gist of it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants