Coder Social home page Coder Social logo

Mocking abstract classes about ts-mockito HOT 23 OPEN

nagrock avatar nagrock commented on September 28, 2024
Mocking abstract classes

from ts-mockito.

Comments (23)

NagRock avatar NagRock commented on September 28, 2024 8

@michalstocki mocking interfaces is planned but rather not in the coming weeks. Also I will need some help with this feature from you.

from ts-mockito.

michalstocki avatar michalstocki commented on September 28, 2024 2

Mocking abstract classes is not a trivial task, because abstract methods do not exist in JavaScript. We can't simply iterate over the object properties to create the correct mock object.

abstract class AbstractClass {
  public abstract getValue():number;

  public getOtherValue():string {
    return '';
  }
}

produces:

    var AbstractClass = (function () {
        function AbstractClass() {
        }
        AbstractClass.prototype.getOtherValue = function () {
            return '';
        };
        return AbstractClass;
    }());

This could potentially be implemented in the way similar to mocking of interfaces (using Proxy object). Maybe using the same technique. However the feature is still not supported. @NagRock could you confirm whether the feature is planned in the nearest future?

const abstractMock:AbstractClass = mockType<AbstractClass>();

from ts-mockito.

pbadenski avatar pbadenski commented on September 28, 2024 2

@woodcockjosh it doesn't seem to be that obvious how this can be implemented easily.. I use this workaround:

interface LoadBalancer {
  calculate: (...) => Promise<any>;
}

const loadBalancerMock =
  mock.mock<LoadBalancer>({ prototype: { calculate: (): any => undefined } } as any);

from ts-mockito.

jimmythompson avatar jimmythompson commented on September 28, 2024 2

@woodcockjosh I'm not sure how you intended that response to come across, but it sounded really douchey. 😕

from ts-mockito.

woodcockjosh avatar woodcockjosh commented on September 28, 2024 2

from ts-mockito.

michalstocki avatar michalstocki commented on September 28, 2024 1

😄 But it's the essential value of an abstract class: it enforces consistency of it's implementations. I think you should not create a special Extension class only for the mocking purpose. You can use one of the extensions already existing in your code.

from ts-mockito.

NagRock avatar NagRock commented on September 28, 2024 1

Thanks to @dyong0 we can now mock abstract and generic types in version 2.1.0 (https://github.com/NagRock/ts-mockito/releases/tag/v2.1.0)!
I will close this issue and open new for interfaces mocking.

from ts-mockito.

woodcockjosh avatar woodcockjosh commented on September 28, 2024 1

When we gonna be able to mock interfaces? It's like really I have to mock an implementation? That's totally broken and defeats the whole point of mocking.

from ts-mockito.

joaovieira avatar joaovieira commented on September 28, 2024 1

+1 for mocking interfaces! 😩

Edit: Just noticed what I wanted is actually pretty easy:

interface ITest {
  one: string;
  two(): number;
}

const service = (dep: ITest) => {
  dep.two();
};

const testMock: Partial<ITest> = {
  two: jest.fn(() => 1),
};

const subject = service(testMock as ITest);

Peaked into https://github.com/jjherscheid/ts-mocks/blob/master/src/mocks/mock.ts

from ts-mockito.

michalstocki avatar michalstocki commented on September 28, 2024

Nevertheless, the simple workaround for lack of this feature is using any extension of the AbstractClass to mock;

// Exntension.ts
export class Extension extends AbstractClass {
  public getValue():number {
    return 1;
  }
}

// test
const abstractMock:AbstractClass = mock(Extension);

Note, that abstractMock is in type of AbstractClass to not allow calling of extra methods that Extenstion could have.

from ts-mockito.

ssynix avatar ssynix commented on September 28, 2024

Thanks for the explanation and the quick response! I'm using the workaround right now. One thing I don't like about it is that any changes in the number or signature of abstract methods has to be replicated in the Extension class.

from ts-mockito.

NagRock avatar NagRock commented on September 28, 2024

@ssynix please give feedback is it works as expected.

from ts-mockito.

dyong0 avatar dyong0 commented on September 28, 2024

@NagRock I found another issue on mocking generics. Mocking a generic class or interface loses members with its generic types. For example, mongoose.Model is an generic interface

interface Model<T extends Document> extends NodeJS.EventEmitter, ModelProperties { ... }

which has

create(docs: any[], callback?: (err: any, res: T[]) => void): Promise<T[]>;
where(path: string, val?: Object): Query<any>;

When you mock it:

let mockedModel = mock(mongoose.Model);
let model = instance(mockedModel);

it loses some parts of its body:
image
yet keeps members without its generic types:
image

Can you please add a note for this issue on mocking generics? README would be nice to place it.

from ts-mockito.

dyong0 avatar dyong0 commented on September 28, 2024

Plus, when you console.log() mocked a generic. It displays null, but actually it's not.

let mockedModel = mock(mongoose.Model);
let model = instance(mockedModel);

console.log(model); // null
model === null; // false

from ts-mockito.

NagRock avatar NagRock commented on September 28, 2024

@dyong0 I will try to fix it instead of adding info in readme. Thanks for reporting this!

from ts-mockito.

NagRock avatar NagRock commented on September 28, 2024

@dyong0 you trying to mock interface (not abstract class) that is not supported yet.

from ts-mockito.

dyong0 avatar dyong0 commented on September 28, 2024

@NagRock right, it doesn't have tests for mocking interfaces. but looks working fine for interfaces too. btw the issue i reported was about mocking generics. i think the same problem happens on generic classes as well as abstract ones.

from ts-mockito.

NagRock avatar NagRock commented on September 28, 2024

@dyong0 could you please provide a sample repository with this? It would be much simpler for me to fix this with project that reproduces issue.

from ts-mockito.

mpiroc avatar mpiroc commented on September 28, 2024

When mocking abstract classes, abstract methods are not mocked (version 2.1.1). I assume that this is the same problem that prevents mocking interfaces, but at minimum the docs should be updated to prevent confusion.

abstract class Foo {
  abstract foo(): void;
  bar(): void {}
}

...

const mock = mock(Foo)
mock.foo // undefined
mock.bar // function

from ts-mockito.

assafaloni avatar assafaloni commented on September 28, 2024

I tried to run @mpiroc example with v2.2.5 and got the same output (foo is undefined),
I did include es6 for tsconfig lib param.

I dont understand - this should be supported now? if so what am i doing wrong?
Thanks!

from ts-mockito.

NagRock avatar NagRock commented on September 28, 2024

Hi, thanks for reporting. I will check it.

from ts-mockito.

julianosam avatar julianosam commented on September 28, 2024

Hey guys. Was this issue solved? I can see the PR that adds support for mocking abstract classes was merged, but I'm still getting the error mentioned by @mpiroc. I'm using version 2.2.9. Thanks

from ts-mockito.

woodcockjosh avatar woodcockjosh commented on September 28, 2024

Fine, I'll do a pull request with a solution. That's obviously not the solution.

from ts-mockito.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.