Skip to content

Assert.That evaluates expression twice #6690

@nohwnd

Description

@nohwnd

Describe the bug

Assert.That evaluates the expression twice (or more times) to extract the values. This can lead to confusing behavior when any of the parts have state or are dynamic / random.

Steps To Reproduce

using System.Diagnostics.CodeAnalysis;

namespace mstest280;

[TestClass]
public sealed class Test2
{
    [TestMethod]
    public void TestMethod1()
    {
        var box = new Box();
        var expected = 2;
        Assert.That(() => box.GetNumber() == expected);
    }
}

public class Box
{
    int _c = 0;
    public int GetNumber()
    {
        _c++;
        return _c;
    }
}

Will fail the assertion, but will report that the values are the same:

Image

This is happening because evaluation happens once to figure out the result of the whole expression:

And then it happens again when getting the details of each detail within the expression:

object? value = Expression.Lambda(expr).Compile().DynamicInvoke();

To solve this problem it needs to happen in one step, invoking while collecting the values.

Expected behavior

It is correctly reported that GetNumber returned 1 when the == evaluation happened.

Actual behavior

It is incorrectly reported that GetNumber returned 2, when the == evaluation happened, showing the user a message that the values were the same.

Metadata

Metadata

Assignees

Labels

Area: AssertionArea: MSTestIssues with MSTest that are not specific to more refined area (e.g. analyzers or assertions)

Type

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions