Hypertest v2 Docs
HyperTest
  • Overview
    • How It Works?
  • SETUP GUIDE
    • Installation
      • Deploy HyperTest Server
      • Creating your first User
      • Adding your first service
      • Integrate SDK
        • Node.js
          • Node.js SDK with CJS
          • Node.js SDK with ESM
        • Java
    • Start a Test Run
      • CLI Login
      • Type References
      • Java
  • Interpreting Test Results
    • Test Results
    • Understanding Results Categories
    • Mock Not Found
    • AI Match Mocks
    • Accepting Changes
  • USER GUIDES
    • Node.js SDK
      • Limit memory usage
      • Supported NPM packages
      • Mock Dependencies Manually
      • Unmocking/Passing Through
      • Sampling and blocking requests
      • Manage Global Variables
      • Mocking Environment Variables
      • Tags
      • Set HTTP path patterns
      • Discard a test case(Request) while recording
      • Set Git Commit Hash
      • Code coverage based features
        • Continuous Coverage
        • Updating test coverage
        • Running post test deduplication
        • Only testing modified requests
        • Ignore differences for unmodified requests
      • Experimental flags
      • Manual Request
      • Only testing modified requests
      • Server hooks
    • Java SDK
      • Sampling and blocking requests
      • Mock Dependencies Manually
      • Tags
      • Unmocking/Passing Through
      • Code Coverage Setup and Report Generation
      • Supported Java packages
    • Build your own Docker Image
    • CLI Config
    • Ignoring Differences
      • Type References for Filter functions
  • Impact Features
    • Fast Mode
    • Code Coverage Report
    • Delete Recorded Requests
    • Inter Service Testing
  • Release History
    • Slack Integration
    • Version History
Powered by GitBook
On this page
  • Manual Mock V2
  • Input Parameters:
  1. USER GUIDES
  2. Node.js SDK

Mock Dependencies Manually

PreviousSupported NPM packagesNextUnmocking/Passing Through

Last updated 7 months ago

HyperTest provides a way for you to manually mock certain dependencies that are not instrumented automatically.

Please check the list of , before proceeding with manual mocks.

These mocks also come in handy when you want to reduce false positives in the test reports caused by a utility that returns arbitrary values e.g., timestamps, and UUIDs.

Let's look at an example where manual mocks can be utilized.

Below is an API route that generates PROMO code for a user.

function generatePromoCode(userId) {
  // Generate a unique promo code based on userId or any other logic
  const uniquePart = uuidv4().split('-')[0]; // Take the first part of a UUID
  return `PROMO-${uniquePart}-${userId}`;
}

app.post('/generate_promo_code', (req, res) => {
  const { emailId } = req.body;
  const userInst = db.User.findOne({ where: { emailId } });
  
  const promoCode = generatePromoCode(userInst.id);
  res.json({ promoCode });
});

If we record this API interaction and run a Test then HyperTest will report a value-modified error, but this is a false positive and it's not a real change that was made in the logic.

To eliminate this recurrent issue we can manually mock the generation of the Promo code. When we re-record this API interaction we will also have the exact value of the Promo code that was generated and the same will be used in the Test.

const { createManualMock } = require('@hypertestco/node-sdk');

app.post('/generate_promo_code', (req, res) => {
  const { emailId } = req.body;
  const userInst = db.User.findOne({ where: { emailId } });
  
  const promoCode = createManualMock({
    uniqueIdentifier: 'generatePromoCode',
    defaultValue: 'PROMO-DEFAULT-123',
    execFn() {
      return generatePromoCode(userInst.id);
    },
  });

  res.json({ promoCode });
});

function generatePromoCode(userId) {
  // Generate a unique promo code based on user_id or any other logic
  const uniquePart = uuidv4().split('-')[0]; // Take the first part of a UUID
  return `PROMO-${uniquePart}-${userId}`;
}

To create a manual mock you need to give these input params:

  • uniqueIdentifier: An identifier is needed to pick the right mock during REPLAY, if you are making the same kind of function calls then consider adding a number to the identifier.

  • defaultValue: A default value is required for a case where we are unable to find the recorded mock, e.g., you changed the identifier value or added a new manual mock and if we run an old recorded test that has different mocks then this default value will be used.

  • execFn: This is a wrapper function that contains the logic you want to mock manually, in RECORD mode the return value of this function will be kept to use in the REPLAY mode(Test).

If we run a test with the manual mock in place it passes.

Manual Mock V2

Allows you to capture mocks with a readable input, which will help you better understand the mocks on the dashboard. Example:

// Async function to check, create, truncate, insert, and select data from a table
async function createTableIfNotExistAndGetData({ users }: {
  users: { name: string; age: number }[]
}) {
  // Logic...
}


const htPatchedFunction = htSdk.createManualMockV2({
  functionType: 'ASYNC',
  identifier: 'createTableIfNotExistAndGetData',
  originalFn: createTableIfNotExistAndGetData,
  thisValue: this,
});

app.get('/test/manualMockV2/async', async (req, res) => {
  const users = [{ name: 'A', age: 2 }, { name: 'B', age: 3 }, { name: 'C', age: 4 }];
  const result = await htPatchedFunction({ users });
  res.send(result);
});

Input Parameters:

1. identifier (string):

  • A unique name for the mock function.

  • Used for correctly Identifying the mock during REPLAY.

Example: 'mock-getUserData'

2. originalFn (Function):

  • The original function being mocked.

  • This function can be synchronous, asynchronous, or callback-based.

3. functionType (FunctionTypeEnum):

  • Describes the type of function being mocked:

    • SYNC: For synchronous functions.

    • ASYNC: For functions that return a Promise.

    • CALLBACK: For functions that take a callback.

4. thisValue (unknown):

  • The value to bind as this when the originalFn is called.

  • Defaults to the current this context, but can be any custom object or value.

5. normalizeInputFn (Function, optional):

  • A function that normalizes or transforms the input arguments.

  • It accepts the same arguments as originalFn and returns an object with normalized input values.

  • Return value of this function will be used as readableInput and would be used for display on dashboard.

Example:

const normalizeInputFn = (...args) => ({ input1: args[0], input2: args[1] });
automatically instrumented packages