How to mock an import
You can assign to sys.modules['B']
before importing A
to get what you want:
test.py:
import sys
sys.modules['B'] = __import__('mock_B')
import A
print(A.B.__name__)
A.py:
import B
Note B.py does not exist, but when running test.py
no error is returned and print(A.B.__name__)
prints mock_B
. You still have to create a mock_B.py
where you mock B
's actual functions/variables/etc. Or you can just assign a Mock()
directly:
test.py:
import sys
sys.modules['B'] = Mock()
import A
How to jest.mock an ES6 module import?
Have you try to mock like this
jest.mock('@mine/my-lovely-libary', () => ({
doSomething: () => doSomethingMock,
}));
here doSomething is a method from your npm library
doSomethingMock can be jest.fn() or something like this const doSomethingMock = 'mockTestValue'
How to mock the import of a module in python?
Since your function search_for_data
is using the name config
imported in func
's global namespace, you need to override that instead of the overriding folder.some_config_module
.
@patch('folder.func.config')
An import like import folder.some_config_module as config
is equivalent to doing:
import folder.some_config_module
config = folder.some_config_module
del folder.some_config_module
Hence it adds the variable config
to that module(func.py
)'s namespace and that's what then search_for_data
is using. From search_for_data
's perspective, it doesn't matter if config
is a name that refers to a module or it refers to something else, it just knows that it needs to load that name from the global namespace(in this case it's the module func.py
)
At runtime search_for_data
will look for config
in its global namespace(search_for_data.__globals__
), mock patches this globals dictionary and replaces the name config
in this dictionary temporarily with the mock object and during teardown it restores it back.
import os.path as path
from unittest.mock import patch
def func():
print(path)
print(f"Before patch: {func.__globals__['path']}")
with patch("__main__.path"):
print(f"During patch: {func.__globals__['path']}")
func()
print(f"After patch: {func.__globals__['path']}")
Outputs:
Before patch: <module 'posixpath' from '/usr/lib/python3.8/posixpath.py'>
During patch: <MagicMock name='path' id='140233829017776'>
<MagicMock name='path' id='140233829017776'>
After patch: <module 'posixpath' from '/usr/lib/python3.8/posixpath.py'>
Spying On/Mocking Import of an Import
Late to the party but just in case anyone else is facing the same issue.
I solved it by importing the module dependency in the test file and mocking the whole module first, then just the methods I needed.
import { client } from 'client';
vi.mock('client', () => {
const client = vi.fn();
client.get = vi.fn();
return { client }
});
Then in those tests calling client.get()
behind the scenes as a dependency, just add
client.get.mockResolvedValue({fakeResponse: []});
and the mocked function will be called instead of the real implementation.
If you are using a default export, look at the vitest docs since you need to provide a default key.
If mocking a module with a default export, you'll need to provide a default key within the returned factory function object. This is an ES modules specific caveat, therefore jest documentation may differ as jest uses commonJS modules.
How can I mock an ES6 module import using Jest?
Fast forwarding to 2020, I found this blog post to be the solution: Jest mock default and named export
Using only ES6 module syntax:
// esModule.js
export default 'defaultExport';
export const namedExport = () => {};
// esModule.test.js
jest.mock('./esModule', () => ({
__esModule: true, // this property makes it work
default: 'mockedDefaultExport',
namedExport: jest.fn(),
}));
import defaultExport, { namedExport } from './esModule';
defaultExport; // 'mockedDefaultExport'
namedExport; // mock function
Also one thing you need to know (which took me a while to figure out) is that you can't call jest.mock() inside the test; you must call it at the top level of the module. However, you can call mockImplementation() inside individual tests if you want to set up different mocks for different tests.
How to mock an import in a different python source under test?
Here's sort of what I'm proposing with the sys.modules
solution. You have options as far as if you want to do that mock
globally, in each test case:
'''bad_module.py'''
raise RuntimeError("don't import me")
'''my_module.py'''
from bad_module import somestuff
def my_func():
pass
'''test_my_module.py'''
import sys
import unittest
from unittest import mock
def test_stuff():
sys.modules['bad_module'] = mock.Mock()
from my_module import my_func
my_func()
If I don't mock I get this:
...
File "/home/wholevinski/so_test/mock_import/test_my_module.py", line 2, in <module>
from my_module import my_func
File "/home/wholevinski/so_test/mock_import/my_module.py", line 1, in <module>
from bad_module import somestuff
File "/home/wholevinski/so_test/mock_import/bad_module.py", line 1, in <module>
raise RuntimeError("don't import me")
RuntimeError: don't import me
----------------------------------------------------------------------
Ran 1 test in 0.001s
FAILED (errors=1)
With the mock I get this:
(p36) [localhost mock_import]$ nosetests test_my_module.py
.
----------------------------------------------------------------------
Ran 1 test in 0.001s
OK
How to mock an imported array and test the using Function
You are testing the check
function, you should NOT stub it. Like your said, you should mock the myarray
in test cases. You could mutate the value of myarray
before require
/import
the checkFunction.js
module. Make sure to clear the module cache before running each test case, so that subsequent imports of the constants
module will give you a fresh myarray
, not the mutated one.
E.g.
constants.js
:
export const myarray = ['apples', 'oranges', 'pears'];
checkFunction.js
:
import { myarray } from './constants';
export function check(value) {
console.log('myarray: ', myarray);
return myarray.includes(value);
}
checkFunction.test.js
:
import { expect } from 'chai';
describe('72411318', () => {
beforeEach(() => {
delete require.cache[require.resolve('./checkFunction')];
delete require.cache[require.resolve('./constants')];
});
it('should pass', () => {
const { myarray } = require('./constants');
myarray.splice(0, myarray.length);
myarray.push('beef', 'lobster');
const { check } = require('./checkFunction');
expect(check('apples')).to.be.false;
});
it('should pass 2', () => {
const { check } = require('./checkFunction');
expect(check('apples')).to.be.true;
});
});
Test result:
72411318
myarray: [ 'beef', 'lobster' ]
✓ should pass (194ms)
myarray: [ 'apples', 'oranges', 'pears' ]
✓ should pass 2
2 passing (204ms)
Related Topics
Is There a Python Equivalent for Rspec to Do Tdd
Simple File Server to Serve Current Directory
Find All Combinations of a List of Numbers with a Given Sum
Splitting a String into Words and Punctuation
How to Capture Multiple Camera Streams with Opencv
In Python Can One Implement Mixin Behavior Without Using Inheritance
Ruby Equivalent to Python's Help()
Is There a Function That Checks If a Character in a String Is a Letter in the Alphabet? (Swift)
How to Round a Floating Point Number Up to a Certain Decimal Place
How to Add Title to Subplots in Matplotlib
Create Dynamic Urls in Flask with Url_For()
How to Fetch a Non-Ascii Url with Urlopen
Convert Column to Date Format (Pandas Dataframe)
Dynamic Instantiation from String Name of a Class in Dynamically Imported Module
What Is Ruby Equivalent of Python's 'S= "Hello, %S. Where Is %S" % ("John","Mary")'
Merge Pandas Dataframes Where One Value Is Between Two Others