title: NestJS architecture and testing
body: <p>I am currently working on a project using NestJS and when it comes to testing I think the architecture is bit of a pain. As far as I understand the recommended approach is to have two layers: controllers and service.</p>
  
  <h2>Controllers</h2>
  
  <p>The controllers is fairly easy to test when needed, although I do not understand the need for testingModules (same goes for services):</p>
  
  <pre class="lang-js prettyprint-override"><code>const module = await Test.createTestingModule({
    controllers: [MyController]
    providers: [MyService] // jest.mock is used to mock MyService
  }).compile();
  
  controller = module.get(MyController)
  </code></pre>
  
  <p>It seems fairly easy to inject whatever mock I need directly:</p>
  
  <pre class="lang-js prettyprint-override"><code>controller = new MyController(new MyService()) // again jest.mock is used to mock MyService
  </code></pre>
  
  <p>For me the latter example is shorter, easier to understand and expresses exactly what I want to test. It does not test that my dependency injection works, but (at least in our application) that is checked by NestJS at startup.</p>
  
  <h2>Services</h2>
  
  <p>When it comes to testing services, I find myself doing a <strong>lot</strong> of mocking of repositories.</p>
  
  <pre class="lang-js prettyprint-override"><code>const spy = jest.spyOn(repository, 'save')
    .mockReturnValueOnce(null) // something like jest-when should be introduced
  
  await service.create('Question on Stackoverflow', 'I do not get it...')
  
  expect(spy.mock.calls[0][0]).toEqual({
    title: 'Question on Stackoverflow',
    content: 'I do not get it...',
    comments: [] // no initial comments
  })
  </code></pre>
  
  <p>Every tutorial/example I've found suggests putting the Repository in the service. I've thought about putting it in the controller (or resolver for GraphQL), but is just doesn't feel like the right separation of responsibilities and leads to duplication of code when both Rest and GraphQL is used. For me the best approach seems to be creating another layer (or add functions to my entity classes), which would then be responsible for the domain/business logic. This is easy to test (no mocks and no promises)</p>
  
  <pre class="lang-js prettyprint-override"><code>const question = Domain.create('Question on Stackoverflow', 'I do not get it...')
  // or const question = Question.create('Question on Stackoverflow', 'I do not get it...')
  
  expect(question).toEqual({
    title: 'Question on Stackoverflow',
    content: 'I do not get it...',
    comments: [] // no initial comments
  })
  </code></pre>
  
  <p>The service would then only be responsible for I/O which seems like a great separation of concerns.</p>
  
  <p>My question is now: does this make sense when it comes to NestJS? It seems like this is not the suggested way to do it. Maybe I am missing some important stuff or maybe I am complicating the architecture more that necessary.</p>
  
  <p>Thanks for your inputs in advance<br>
  Andreas</p>