0

I couldn't find any example for XUnit, although I know JUnit and Moq have this option.

I have a string that contains 3 times the same substring, or should, and I want to assert that. I am using XUnit but I cannot find any way of asserting this in a clean way, using something that the library offers.

Is there any out-of-the-box option for this?

Michał Turczyn
  • 32,028
  • 14
  • 47
  • 69
S. Dre
  • 647
  • 1
  • 4
  • 18
  • 2
    That doesn't sound like a common requirement to me, so I'd be surprised to find it exists out of the both. – Jon Skeet May 16 '23 at 10:45
  • Actually I just realized a regex should do it. But I'll leave the question open, I think it can be useful for someone looking for the same thing. – S. Dre May 16 '23 at 10:55
  • I'm curious, how would you do that in JUnit and Moq? – Good Night Nerd Pride May 16 '23 at 11:03
  • Not out of the box, but you can [count the substring occurrences](https://stackoverflow.com/questions/15577464/how-to-count-of-sub-string-occurrences). – CodeCaster May 16 '23 at 12:02

1 Answers1

1

For that purpose I would define extension method that would do correct assertion:

public static class TestUtils
{
    public static void AssertContainsXTimes(this string actual, string expectedSubstring, int times)
    {
        var actualRemovedLength = actual.Length - actual.Replace(expectedSubstring, string.Empty).Length;
        var expectedRemovedLength = expectedSubstring.Length * times;

        Assert.Equal(expectedRemovedLength, actualRemovedLength);
    }

    public static void AssertContainsAtLeastXTimes(this string actual, string expectedSubstring, int times)
    {
        var actualRemovedLength = actual.Length - actual.Replace(expectedSubstring, string.Empty).Length;
        var expectedRemovedLength = expectedSubstring.Length * times;

        Assert.True(actualRemovedLength >= expectedRemovedLength);
    }
}

And below is the screenshot of sample unit tests with their result for better understanding: enter image description here

Michał Turczyn
  • 32,028
  • 14
  • 47
  • 69
  • This is dirty though, as it leaves a garbage string after replacing. Also, does "eeee" contain "ee" twice or thrice? – CodeCaster May 16 '23 at 12:01
  • @CodeCaster IMO matches should not overlap, i disagree that it's dirty ? In what way? But let's see if OP will find my answer useful – Michał Turczyn May 16 '23 at 12:52
  • "as it leaves a garbage string after replacing" – CodeCaster May 16 '23 at 12:52
  • @CodeCaster well , i can read :) i meant that it's totally unclear what you have meant by that – Michał Turczyn May 16 '23 at 12:54
  • `string.Replace()` returns a new string after replacing, if something was replaced. This increases memory usage. It generates a garbage string for the garbage collector to collect. It is a wasteful implementation of a substring count. – CodeCaster May 16 '23 at 12:56