Is anyone using Jest to unit tests? If so, is ther...
# suitescript
s
Is anyone using Jest to unit tests? If so, is there a way to mock a private function? It's driving me crazy and I have browed a lot for info. If I want to check if a private function was called, I can't. If I need that private function to return something, I can't.
s
This is a long standing issue that isn't unique to javascript or NetSuite. you'll either have to make the function callable from the outside or change your design (e.g. perhaps that private function might better live somewhere else)
s
I see examples online, but I guess because we're using RequireJS those examples don't work. I've seen somethings about Rewire but I haven't been able to get that to work either. Might be because it is using RequireJS. Man, it's frustrating
s
yes, there are different techniques, depending on the capabilities of the platform.
It's always felt dirty to me to expose a method as public that would otherwise intentionally remain private.
c
Can you not use the jest's spyon?
s
@creece Nah, I get this error
Error: Cannot spy the processPreAuthFailure property because it is not a function; undefined given instead
I removed stuff, but this is my setup
Copy code
define(['../../../../src/FileCabinet/SuiteScripts/AccentDecor/implementation/Pre-auth/ad_sl_run_pre_auth'], function (preAuth) {
    beforeEach(() => {
        jest.clearAllMocks();
    });

    describe('Send to Preauth', () => {
        it('No payment event - ', () => {
            const ctx = {
                request: { parameters: { soId: 555, processPreAuthFailed: true, isReleaseToWMS: false } },
                response: { write: jest.fn() }
            };
            const spy = jest.spyOn(preAuth, 'processPreAuthFailure');
            preAuth.onRequest(ctx);

            expect(preAuth.processPreAuthFailure).toHaveBeenCalled(1);
        });
    });
});
d
I don't think it will necessarily improve/solve your issue, but is there a reason you're using RequireJS module style for the tests themselves? should be more streamlined to use newer import/export syntax etc. like in NS examples https://github.com/oracle/netsuite-suitecloud-sdk/tree/master/packages/unit-testing#suitecloud-unit-testing-examples
however, in that example I'd think would generally be
expect(spy).toHaveBeenCalled...
placing assertion on the declared spy instead
s
Haha, i did it because webstorms auto complete works. So when I mock a library, I have code completion
👍 1
It errors when trying to create the spy though 😕
d
so "processPreAuthFailure" is private with respect to preAuth module? or it is at least exported/returned from there
s
Yes, "processPreAuthFailure" is private with respect to preAuth
d
hmm gotcha ya i don't think there's really a way then as it stands without reworking the code/modules structure some to support your testing requirements
👍🏼 1
c
The only other way is expose it via a public method and call that method which you can test. If you're putting this much effort into a unit test, it would definitely make me think about the code organization/structure. It could be you just have a few things to switch around to make it easier to test. I don't use typescript myself so my knowledge of it is pretty limited.
s
Yeah, I'm not using typescript either, but to re-arrange do you have an example of what you mean? do you mean separate the logic into a separate file, and then make all of those calls public?
c
Yeah you basically create a public interface w/ your private method as the implementation.
you don't really care WHAT the method does, only that it is called
s
Yeah
c
thats totally fine to have a public method w/ a private implementation.
s
Man, so basically a script file for the trigger script (user event/client) --> business logic --> private methods
It is, I just dislike all the clutter if I ever use it. I like my pretty, "here's a couple of methods for you to call" instead of the additional files. If I go a 3 file structure, that helps, but I'll probably be lazy and just make everything public in the BL file
🍺 1
c
That structure also allows you to easily change the underlying implementation. If all of your files call the public "processPreAuthFailure" then it doesn't matter what the implementation does as thats internal and can be swapped at will. It will actually lead itself to a more maintainable app because now you can change the implementation of what is going on without touching the rest of the code..
👍🏼 1
Its basically "programming to an interface" lite version
s
Yeah, that's what I did back when I worked with C#
👍 1