title: How to write Jest unit test for node controller
body: <p>I'm new to unit test and tried to write test for my controller (ProgramsController).According to my understanding i want to mock my <code>programService</code> and it return values.
  I would really appreciate some one can fix this.then i can get idea and write jest test for other services.</p>
  <p>I tried as below and got error</p>
  <p><strong>ProgramsController.js</strong></p>
  <pre><code>class ProgramsController {
      constructor() {
          this.programService = new ProgramService();
      }
      async subscribe(req, res) {
          const { userId, uuid, msisdn, body: { programId } } = req;
          const data = { userId, programId, msisdn, uuid }
  
          const subscribe = await this.programService.subscribeUser(data);
          res.send({
              status: true,
              message: constant.MSG.SUCCESS,
              friendly_message: constant.MSG.SUCCESS,
              data: subscribe
          }
      }
  }
  module.exports = ProgramsController;
  </code></pre>
  <p><strong>ProgramService.js</strong></p>
  <pre><code>class ProgramService {
  
      constructor() {
          this.subscriber = new Subscriber();
          this.subsciberProgram = new SubsciberProgram()
      }
  
      async subscribeUser(data) {
          try {
              const { msisdn, userId, programId, uuid } = data;
                  ...
  
              return subscribedData;
  
          } catch (error) {
              throw error;
          }
      }
  }
  module.exports = ProgramService;
  </code></pre>
  <p>test.spec.js</p>
  <pre><code>const ProgramsService = require('../src/services/program/programService')
  const ProgramsController = require('../src/controllers/programs/programsController')
  const programController = new ProgramsController()
  const programsService = new ProgramsService()
  
  
  describe(&quot;Check method \'subscribe\' &quot;, () =&gt; {
      it('should retrieve success', async () =&gt; {
  
          const serviceRecord = { userId: 1, programId: 1, msisdn: '56768382967', uuid: '46651a19-3ef1-4149-818e-9bd8a5f359ef' };
  
          jest.spyOn(programsService, 'subscribeUser').mockResolvedValueOnce(serviceRecord);
  
          const mReq = { body: { programId: 1 }, userId: 1, msisdn: '56768382967', uuid: '46651a19-3ef1-4149-818e-9bd8a5f359ef' };
          const mRes = { status: jest.fn().mockReturnThis(), send: jest.fn() };
  
  
          await programController.subscribe(mReq, mRes);
  
          expect(programsService.subscribeUser).toBeCalledWith(serviceRecord);
          expect(mRes.status).toBeCalledWith(200);
  
          expect(mRes.send).toBeCalledWith({ program_id: 1, amount: 5, no_of_questions: 10 });
      });
  });
  </code></pre>
  <p><a href="https://i.stack.imgur.com/cNAHT.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/cNAHT.png" alt="Jest test" /></a></p>
  <p><strong>------- *** Update (for @tmhao2005) *** ---------</strong></p>
  <p><strong>test.spec.js</strong></p>
  <pre><code>const ProgramsController = require('../src/controllers/programs/programsController')
  
  const serviceRecord = { userId: 1, programId: 1, msisdn: '56768382967', uuid: '46651a19-3ef1-4149-818e-9bd8a5f359ef' };
  
  // Mock subscribe user fn
  const mockSubscribeUser = jest.fn().mockResolvedValue(serviceRecord);
  
  // Mock the service
  class MockService {
    subscribeUser = mockSubscribeUser;
  }
  
  // Apply the mock before the test run
  jest.mock('../src/services/program/programService', () =&gt; MockService)
  
  describe(&quot;Check method \'subscribe\' &quot;, () =&gt; {
    it('should retrieve success', async () =&gt; {
      const mReq = { body: { programId: 1 }, userId: 1, msisdn: '56768382967', uuid: '46651a19-3ef1-4149-818e-9bd8a5f359ef' };
      const mRes = { status: jest.fn().mockReturnThis(), send: jest.fn() };
  
      const programController = new ProgramsController()
      await programController.subscribe(mReq, mRes);
  
      expect(mockSubscribeUser).toBeCalledWith(serviceRecord);
      expect(mRes.status).toBeaCalledWith(200);
  
      expect(mRes.send).toBeCalledWith({ program_id: 1, amount: 5, no_of_questions: 10 });
    });
  });
  </code></pre>
  <p><a href="https://i.stack.imgur.com/R8K6W.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/R8K6W.png" alt="enter image description here" /></a></p>