Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to mock the Type with new() #21

Open
tommy20061222 opened this issue May 14, 2018 · 2 comments
Open

How to mock the Type with new() #21

tommy20061222 opened this issue May 14, 2018 · 2 comments

Comments

@tommy20061222
Copy link

tommy20061222 commented May 14, 2018

// fooBar.ts 
interface bar {
    helloworld: () => string;
}
export type middlewareTypeFoo = {
    new (): bar
};
// safeMock.ts
import {middlewareTypeFoo} from './fooBar';
export class fooBarImpl {
    public invokeAll(listOfthings: middlewareTypeFoo[]) {
        return listOfthings.map((item: middlewareTypeFoo) => {
            return new item().helloworld();
        });
    }
}
// safeMock.test.ts
import {Mock, SafeMock, when} from 'safe-mock';
import {middlewareTypeFoo} from './fooBar';
import {fooBarImpl} from './safeMock';
describe('foobar Test', () => {
    it ('foobar', () => {
        const foobar1 = SafeMock.build<middlewareTypeFoo>();
        const response = new fooBarImpl().invokeAll([foobar1]);
        console.log(response);
    });
})

Hey, Matt, if you copy above three sections of code into three separate files, then console.log(response) in the safeMock.test.ts prints out TypeError: (intermediate value).helloworld is not a function. My question is how should i mock new method on this object? I tried when(foobar1.new), but won't even pass compiler. If i can somehow mock new, then i can probably mock helloworld as well. Thank you for the help!

@matthewmcnew
Copy link
Owner

Hey @tommy20061222!

Interesting find for sure. Some hairy details: Safe-Mock currently does not support mocking the new operator because we have not built in support for the Proxy Construct operation.

I will look at adding that support this week. I spent a bit of time playing with the syntax today for verify and when when used with new. Suggestions welcome!

In the meantime!

I would encourage you to avoid needing to mock the new at all. For inspiration, I looked at Mockito's wiki, a Java mocking library with a great wiki on all things mocking. Mockito also doesn't support mocking new on Java objects and they have a good summary of workarounds here: https://github.com/mockito/mockito/wiki/Mocking-Object-Creation. Basically, create another factory object or function and mock that. An example based on your example is included below:

// fooBar.ts 
interface bar {
    helloworld: () => string;
}
export type middlewareTypeFoo = () => bar;
// safeMock.ts
import {middlewareTypeFoo} from './fooBar';
export class fooBarImpl {
    public invokeAll(listOfthings: middlewareTypeFoo[]) {
        return listOfthings.map((item: middlewareTypeFoo) => {
            return item().helloworld();
        });
    }
}
// safeMock.test.ts
import {Mock, SafeMock, when} from 'safe-mock';
import {middlewareTypeFoo} from './fooBar';
import {fooBarImpl} from './safeMock';
describe('foobar Test', () => {
    it ('foobar', () => {
        const foobar1 = SafeMock.buildFunction<middlewareTypeFoo>();
        const response = new fooBarImpl().invokeAll([foobar1]);
        console.log(response);
    });
})

Cheers!

@tommy20061222
Copy link
Author

thx. @matthewmcnew. I was thinking about this last night and was reading one of the Stackflow thread which suggest same thing you mentioned above. Thank you for the help! At meantime, Please keep me in loop regarding you will add Proxy Construct to the library.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants