I’m a bit confused whether I’m doing this right because every resource I google for has a different way of setting it up.

Some of them initialize the dbContext right in the test class, some do in the WebAppFactory’s ConfigureServices (or is it ConfigureTestServices?).

Some do it in the IAsyncLifetime’s InitializeAsync, some do it as a dependency injection and other examples just put it as a member variable in the factory.

I don’t wanna code dump my project here and ask for someone to solve it but I am not sure anymore what to do. My current attempt is using an sqlite database and it is breaking when I try to run all the tests at the same time due to this.

Makes sense since they are all using the same db in this case so I tried following a guide and just letting them use the :memory: one but that one, for some reason, doesn’t seem to initialize the database at all and tests fail because the database doesn’t have any tables.

I also added a CollectionDefinition with an ICollectionFixture for each individual test class (one per controller so far) thinking this might cause each test to have its own separate database (or factory?) but that didn’t really do anything.

I’m hoping someone experienced can probably immediately recognize what am I missing, or at the very least give me a solid resource that I could read to figure this out, but any help is appreciated.

  • Kissaki
    link
    fedilink
    English
    arrow-up
    1
    ·
    edit-2
    11 days ago

    From your screenshot, for the memory solution, you’re attempting to open a single connection (Singleton service, connection Open) for an arbitrary number? or single that you use in parallel? db context.

    When using dependency injection, you should set it up with a factory, and then inject the factory and create db connections from that, which will use and open a specified connection.

    For unit tests you will want to ensure each test run instantiates its own database, in a defined state. Then they can run in parallel.

    To improve efficiency, it may be possible to set up one DB for read-only tests, or separate tables or schema for test cases. Which may or may not make sense depending on what you want to test. Separation is better to start with.

    • CynoOP
      link
      fedilink
      arrow-up
      1
      ·
      edit-2
      11 days ago

      Configuring a DbContextFactory in the WebAppFactory instead of a DbContext breaks my services, they can’t resolve DbContext anymore so all requests from my test classes fail. Either I misunderstood you or how this works, but it makes sense - I need to properly fix the injectable DbContext so it fixes it everywhere and not just add a DbContextFactory for test classes while the actual code still injects a DbContext.

      Configuring the DbConnection service scope as Transient didn’t change anything.

      I might consider efficiency and speed later but for now I’d be happy to just get it working on this simple CRUD app with 2 test classes, I’ve spend hours trying various google solutions and I’m a bit frustrated there is no simple guide for something that should be so seemingly simple at this point.

      • Kissaki
        link
        fedilink
        English
        arrow-up
        1
        ·
        10 days ago

        You said you didn’t want to code dump the entire project here, but a minimal example that demonstrates your project setup and intention could help.

        Looking at your first screenshot, I’m not sure what your intention was when you tried out the commented out code and what else you tried.

        But have you tried configuring the context to use a memory data source string?

        You want to run the app with memory, right?

        How do you intend to run the integration tests vs normal app? How do you differentiate those two in configuration and startup?

        • CynoOP
          link
          fedilink
          arrow-up
          1
          ·
          edit-2
          10 days ago

          My first intent was to just have one local sqlite test db that would get reset to empty state before the tests run (EnsureDeleted+EnsureCreated), and then they all run concurrently on it. It sounded simple to setup and simple enough for my small crud app that only had a few tests.

          My second intent was for the framework to create a new in-memory sqlite db for each test so I could fix the problem with tests failing when I’d run all of them at the same time, presumably because they all referenced the same db.

          I am currently trying to complicate my life further in the hopes it helps with this by using a postgres database instead, and then in the IntegrationTests project I’m using TestContainers to get a PostgreSqlContainer. I am currently suffering because of some change I made so my tests aren’t even being found anymore now, despite being listed in the test explorer when I run them I get “Test discovery finished: 0 Tests found” in output. Honestly I think I’m just gonna give up integration testing like this, it’s been a complete waste of time so far.

          Dunno what else I could say about my project that is relevant, it’s a standard webapp crud with 2 controllers and the integration tests projects has facts like this. Very basic stuff I’d say. Unit tests are a separate project and will just be for simple method checks, no mocking (or at least as little as possible)

          • Kissaki
            link
            fedilink
            English
            arrow-up
            2
            ·
            10 days ago

            have one local sqlite test db that would get reset to empty state before the tests run (EnsureDeleted+EnsureCreated), and then they all run concurrently on it.

            Doesn’t that contradict?

            You can’t have the single DB reset at the beginning of tests if the tests run concurrently.

            • CynoOP
              link
              fedilink
              arrow-up
              1
              ·
              edit-2
              9 days ago

              You are probably right and I just misunderstood fixtures / collections and how they work. I am now trying to configure it using postgres testcontainers and just letting each test create its own but facing a bunch of other issues so not even sure how this works anymore, seems like every tutorial has a different approach. Some just put all the code for creating containers in the setup/dispose of the test class itself instead of trying to be smart with the WebApplicationFactory fixtures and maybe I just end up doing that

              • Kissaki
                link
                fedilink
                English
                arrow-up
                1
                ·
                edit-2
                9 days ago

                I’m sure you have to launch the integration tests in some way parameterized. Why can’t you make the DB data source depend on that parameter[ization]?

                I’m not sure if you’re past the DB concern now or not.