Skip to content

Commit

Permalink
feat: ngMocks.stubMember returns passed value
Browse files Browse the repository at this point in the history
  • Loading branch information
satanTime committed Jan 10, 2021
1 parent 06b265f commit 27f5404
Show file tree
Hide file tree
Showing 4 changed files with 62 additions and 9 deletions.
12 changes: 12 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2867,6 +2867,18 @@ ngMocks.stubMember(service, property, customGetter, 'get');
ngMocks.stubMember(service, property, customSetter, 'set');
```

It returns the passed value, therefore, this allows **fast chains for spies** and mocks.

```ts
ngMocks
.stubMember(service, 'handler', jasmine.createSpy('handler'))
.and.returnValue('fake');

ngMocks
.stubMember(service, 'read', jasmine.createSpy('read'), 'set')
.and.toThrowError();
```

If we need to stub a method of a service in Angular tests:

```ts
Expand Down
4 changes: 3 additions & 1 deletion lib/mock-helper/mock-helper.stub-member.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
export default <T extends object>(instance: T, key: any, value: any, encapsulation?: 'get' | 'set'): void => {
export default <T extends object>(instance: T, key: any, value: any, encapsulation?: 'get' | 'set'): any => {
const def = Object.getOwnPropertyDescriptor(instance, key) || {};

const descriptor: PropertyDescriptor = {
Expand All @@ -18,4 +18,6 @@ export default <T extends object>(instance: T, key: any, value: any, encapsulati
}

Object.defineProperty(instance, key, descriptor);

return value;
};
21 changes: 13 additions & 8 deletions lib/mock-helper/mock-helper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -270,24 +270,29 @@ export const ngMocks: {
stub<I extends object>(instance: I, overrides: Partial<I>): I;

/**
* @see https://github.com/ike18t/ng-mocks#ngmocksstubMember
* @see https://github.com/ike18t/ng-mocks#ngmocksstubmember
*/
stubMember<T extends object, K extends keyof T>(instance: T, name: K, stub: () => T[K], encapsulation: 'get'): void;
stubMember<T extends object, K extends keyof T, S extends () => T[K]>(
instance: T,
name: K,
stub: S,
encapsulation: 'get',
): S;

/**
* @see https://github.com/ike18t/ng-mocks#ngmocksstubMember
* @see https://github.com/ike18t/ng-mocks#ngmocksstubmember
*/
stubMember<T extends object, K extends keyof T>(
stubMember<T extends object, K extends keyof T, S extends (value: T[K]) => void>(
instance: T,
name: K,
stub: (value: T[K]) => void,
stub: S,
encapsulation: 'set',
): void;
): S;

/**
* @see https://github.com/ike18t/ng-mocks#ngmocksstubMember
* @see https://github.com/ike18t/ng-mocks#ngmocksstubmember
*/
stubMember<T extends object, K extends keyof T>(instance: T, name: K, stub: T[K]): void;
stubMember<T extends object, K extends keyof T, S extends T[K]>(instance: T, name: K, stub: S): S;

/**
* Thanks Ivy, it doesn't throw an error and we have to use injector.
Expand Down
34 changes: 34 additions & 0 deletions tests/ng-mocks-stub-member/test.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { MockBuilder, MockRender, ngMocks } from 'ng-mocks';
@Injectable()
class TargetService {
public readonly name = 'target';
public norm = 'normal';

public echo(): string {
return this.name;
Expand Down Expand Up @@ -71,4 +72,37 @@ describe('ng-mocks-stub-member', () => {
ngMocks.stubMember(test as any, 'name', 'test');
expect((test as any).name).toEqual('test');
});

it('returns the passed value', () => {
const service = MockRender(TargetService).point.componentInstance;

// checking methods
expect(service.echo()).toEqual('target');
ngMocks
.stubMember(service, 'echo', jasmine.createSpy('echo'))
.and.returnValue('spy');
expect(service.echo()).toEqual('spy');

// checking getters
expect(service.name).toEqual('target');
ngMocks
.stubMember(service, 'name', jasmine.createSpy('name'), 'get')
.and.returnValue('spy');
expect(service.name).toEqual('spy');

// checking setters
ngMocks
.stubMember(service, 'name', jasmine.createSpy('name'), 'set')
.and.throwError('spy');
expect(() => ((service as any).name = 'target')).toThrowError(
'spy',
);

// checking real prop
expect(service.norm).toEqual('normal');
ngMocks
.stubMember(service, 'norm', jasmine.createSpy('norm'), 'get')
.and.returnValue('spy');
expect(service.norm).toEqual('spy');
});
});

0 comments on commit 27f5404

Please sign in to comment.