英文:
Is it possible to mock an internal class object used in a method using Jest
问题
这是您要翻译的代码部分:
import { ProductMetadata } from './product/metadata'
import { LookupService } from './service/lookup'
import { DataHandler } from './product-handlers/data-handler'
class ProductDatatHandler {
async process(data: ProductMetadata, service: LookupService): Promise<void> {
if (data.value) {
try {
const processor = await service.getProductHandlerForType(data.type)
const dataHandler = new DataHandler(processor)
await dataHandler.insert(data)
} catch (error) {
console.error('Failed to persist data ', error)
}
}
}
}
export { ProductDatatHandler }
您尝试模拟的部分是这一行:困难在于它是在内部创建的。我不知道Jest是否有一种方法来模拟这一行。一切都运行正常,只是dataHandler
未定义。
const dataHandler = new DataHandler(processor)
我尝试使用以下方法,但收到了TypeError DataHander is not a constructor
错误:
jest.mock('./product-handlers/data-handler', () => (
{
__esModule: true,
insert: jest.fn()
}
))
还有一个相关的类的导入:
import {ProductProcessor } from './processor/product-processor'
class DataHandler {
private productProcessor:ProductProcessor
constructor(productProcessor: ProductProcessor){
this.productProcessor = productProcessor
}
...
}
请注意,我没有翻译您的问题部分,只提供了代码的翻译。如果您需要进一步的帮助或解释,请告诉我。
英文:
I have a class whose sole function is to process a data type called ProductMetadata
. There is a lookup service that picks a handler depending on the ProductMetadata
type that is passed to the method by a LookupService
object. I am able mock all the other objects except the DataHander
object that's created in the process method
Here is the code
import { ProductMetadata } from './product/metadata'
import { LookupService } from './service/lookup'
import { DataHandler } from './product-handlers/data-handler'
class ProductDatatHandler {
async process(data: ProductMetadata, service: LookupService): Promise<void> {
if (data.value) {
try {
const processor = await service.getProductHandlerForType(data.type)
const dataHandler = new DataHandler(processor)
await dataHandler.insert(data)
} catch (error) {
console.error('Failed to persist data ', error)
}
}
}
}
export { ProductDatatHandler }
The portion I am unable to mock successfully is this line: The difficulty is that it is created internally. I don't know if Jest has a way to mock this line. Everything works except that the dataHandler
is undefined.
const dataHandler = new DataHandler(processor)
How can I mock the DataHandler
class?
I tried using this but I got a TypeError DataHander is not a constructor
jest.mock('./product-handlers/data-handler', () => (
{
__esModule: true,
insert: jest.fn()
}
))
```ts
import {ProductProcessor } from './processor/product-processor'
class DataHandler {
private productProcessor:ProductProcessor
constructor(productProcessor: ProductProcessor){
this.productProcessor = productProcessor
}
...
}
答案1
得分: 2
以下是您要翻译的内容:
"You didn't mock the ./product-handlers/data-handler
module and DataHandler
class correctly. Use jest.mock()
to mock a module with an auto-mocked version.
"jest": "^26.6.3"
product-data-handler.js
:
import { DataHandler } from './product-handlers/data-handler';
class ProductDatatHandler {
async process(data, service) {
if (data.value) {
try {
const processor = await service.getProductHandlerForType(data.type)
const dataHandler = new DataHandler(processor)
await dataHandler.insert(data)
} catch (error) {
console.error('Failed to persist data ', error)
}
}
}
}
export { ProductDatatHandler }
product-handlers/data-handler.js
class DataHandler {
insert(data) {
return Promise.resolve('ok')
}
}
export { DataHandler };
product-data-handler.test.js
:
import { DataHandler } from './product-handlers/data-handler'
import { ProductDatatHandler } from './product-data-handler'
jest.mock('./product-handlers/data-handler');
describe('76429246', () => {
test('should pass', async () => {
const dataHandlerInstanceMock = {
insert: jest.fn()
}
DataHandler.mockImplementation(() => dataHandlerInstanceMock);
const lookUpServiceMock = {
getProductHandlerForType: jest.fn()
}
const productDataHandler = new ProductDatatHandler();
await productDataHandler.process({ type: 'a', value: 'b' }, lookUpServiceMock);
expect(lookUpServiceMock.getProductHandlerForType).toHaveBeenCalledWith('a');
expect(dataHandlerInstanceMock.insert).toHaveBeenCalledWith({ type: 'a', value: 'b' });
});
});
Test result:
PASS stackoverflow/76429246/product-data-handler.test.js (18.035 s)
76429246
✓ should pass (6 ms)
Test Suites: 1 passed, 1 total
Tests: 1 passed, 1 total
Snapshots: 0 total
Time: 18.944 s, estimated 25 s
UPDATE:
You can handle the TS type using jest.mocked(source, options?)
const DataHandlerMock = jest.mocked(DataHandler);
// ...
DataHandlerMock.mockImplementation(() => dataHandlerInstanceMock);
英文:
You didn't mock the ./product-handlers/data-handler
module and DataHandler
class correctly. Use jest.mock()
to mock a module with an auto-mocked version.
"jest": "^26.6.3"
product-data-handler.js
:
import { DataHandler } from './product-handlers/data-handler'
class ProductDatatHandler {
async process(data, service) {
if (data.value) {
try {
const processor = await service.getProductHandlerForType(data.type)
const dataHandler = new DataHandler(processor)
await dataHandler.insert(data)
} catch (error) {
console.error('Failed to persist data ', error)
}
}
}
}
export { ProductDatatHandler }
product-handlers/data-handler.js
class DataHandler {
insert(data) {
return Promise.resolve('ok')
}
}
export { DataHandler };
product-data-handler.test.js
:
import { DataHandler } from './product-handlers/data-handler'
import { ProductDatatHandler } from './product-data-handler'
jest.mock('./product-handlers/data-handler');
describe('76429246', () => {
test('should pass', async () => {
const dataHandlerInstanceMock = {
insert: jest.fn()
}
DataHandler.mockImplementation(() => dataHandlerInstanceMock);
const lookUpServiceMock = {
getProductHandlerForType: jest.fn()
}
const productDataHandler = new ProductDatatHandler();
await productDataHandler.process({ type: 'a', value: 'b' }, lookUpServiceMock);
expect(lookUpServiceMock.getProductHandlerForType).toHaveBeenCalledWith('a');
expect(dataHandlerInstanceMock.insert).toHaveBeenCalledWith({ type: 'a', value: 'b' });
});
});
Test result:
PASS stackoverflow/76429246/product-data-handler.test.js (18.035 s)
76429246
✓ should pass (6 ms)
Test Suites: 1 passed, 1 total
Tests: 1 passed, 1 total
Snapshots: 0 total
Time: 18.944 s, estimated 25 s
UPDATE:
You can handle the TS type using jest.mocked(source, options?)
const DataHandlerMock = jest.mocked(DataHandler);
// ...
DataHandlerMock.mockImplementation(() => dataHandlerInstanceMock);
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论