2

I have some large test suites so I broke them into inner/nested classes. That also makes the results in the VSCode test explorer more friendly.

But it doesn't work well when there's common fixture data that's defined in the outer class:

public class UserTests
{
  // common fixture data used by all inner classes
  public UserTests() => _fake = new Fake();
  private readonly Fake _fake;

  public class AddUser {

    public AddUser(UserTests o) => _outer = o;
    private readonly UserTests _outer;

    [Fact]
    public void test_foo() {
      // use _outer._fake
    }

    [Fact]
    public void test_bar() {
      // use _base._fake
    }
  }

  public class FindUser 
  {
    // ...similar to above
  }

  public class DeleteUser {
    // ...similar to above
  }
}

But I get this error:

The following constructor parameters did not have matching fixture data: UserTests o

So maybe the above is a bad setup.

What's a good setup that allows me to have nested classes and also create fixture data in the outer class, so it can be used by all inner classes?

lonix
  • 14,255
  • 23
  • 85
  • 176
  • Consider creating a separate class you can inject into your test classes which contains these fakes and utility methods. This lets you reuse across many test files instead of having to put everything into one file. – AndreasHassing Jul 16 '21 at 08:59
  • @AndreasHassing Agreed! But sometimes they are single-use for that particular suite and just defined inline. Also, that still wouldn't work as it would be applied in the outer class, but the inner class gives the above error. – lonix Jul 16 '21 at 09:09
  • I think you need to use a [class fixture](https://xunit.net/docs/shared-context#class-fixture) which does what I said and will solve your problems (if I understand them correctly). – AndreasHassing Jul 16 '21 at 20:21
  • 1
    What is the reason of using nested classes?(for example why not to brake into separate classes inside one namespace(folder)) – Fabio Jul 17 '21 at 20:15
  • @Fabio In this case because they're all related (same class). Better than having multiple test classes to test one class. The idea of using subclasses is to make the test explorer and cli reporters more friendly. – lonix Jul 18 '21 at 03:08
  • 1
    Anyway, test runner don't know how to instantiate your test classes, you can call `_outer = new UserTests()` inside the constructor of inner classes. You can wrap outer class within fixture and then pass it as argument to the constructor of inner class. – Fabio Jul 18 '21 at 06:00
  • @Fabio That worked, thanks! If you add as an answer I'll close. – lonix Jul 19 '21 at 13:13

1 Answers1

1

As explained by @Fabio in comments above, the test runner doesn't know how to instantiate the test classes.

So the trick is to call _outer = new UserTests() in the inner class' constructor.

lonix
  • 14,255
  • 23
  • 85
  • 176