Dane Decker
Dane Decker

Reputation: 41

How to mock or stub process.argv

How do I mock or stub process.argv so that it can return a specific argument?

I tried using Sinon.js like this:

beforeEach(
  () => {
    sandbox.stub(
      process.argv.slice(2)[0], 'C:\\home\\project\\assignment'
    ).value('--local');
  }
);

afterEach(
  () => {
    sandbox.restore();
  }
);

test(
  'it replace value of node argument',
  () => {
    assert(process.argv.slice(2)[0], '--local');
  }
);

But I keep getting an error that says trying to stub property 'C:\\home\\project\\assignment' of undefined.

Upvotes: 4

Views: 2769

Answers (3)

Since 29.x, Jest has a replaceProperty method.

jest.replaceProperty(process, 'argv', ['what', 'ever', 'you', 'like']);

The advantage is this mock can be reverted.

Upvotes: 6

Géry Ogam
Géry Ogam

Reputation: 8047

If you prefer to modify process.argv in the tests instead of rebinding it like in @LinDu’s answer, you can save and restore process.argv by making each test work on its own* shallow copy of the original process.argv, so that the tests don’t affect one another:

import assert from 'node:assert/strict';
import test from 'node:test';

test.describe(
  () => {
    const originalArgv = process.argv;

    test.beforeEach(
      () => {
        process.argv = [...originalArgv];  // own shallow copy
      }
    );

    test.test(
      () => {
        process.argv[1] = '--local';
        assert.equal(process.argv[1], '--local');
      }
    );
  }
);

* Note that making each test work on a shared shallow copy of the original process.argv won’t work since the tests will affect one another:

// THIS CODE IS INCORRECT!

import assert from 'node:assert/strict';
import test from 'node:test';

test.describe(
  () => {
    const originalArgv = [...process.argv];  // shared shallow copy

    test.beforeEach(
      () => {
        process.argv = originalArgv;
      }
    );

    test.test(
      () => {
        process.argv[1] = '--local';
        assert.equal(process.argv[1], '--local');
      }
    );
  }
);

Upvotes: 1

Lin Du
Lin Du

Reputation: 102487

You can rebind process.argv (cf. Modify node process environment or arguments runtime):

import assert from 'node:assert/strict';
import test from 'node:test';

test.describe(
  () => {
    const originalArgv = process.argv;

    test.afterEach(
      () => {
        process.argv = originalArgv;
      }
    );

    test.test(
      () => {
        process.argv = process.argv.slice(0, 1).concat(['--local']);
        assert.equal(process.argv[1], '--local');
      }
    );
  }
);

Upvotes: 3

Related Questions