nagrock / ts-mockito Goto Github PK
View Code? Open in Web Editor NEWMocking library for TypeScript
License: MIT License
Mocking library for TypeScript
License: MIT License
Verify does not work when the method under verification has more than 1 argument. This is because in the method isApplicable of the class MethodAction the variable index is not being incremented.
Bellow is the method isApplicable already fixed.
public isApplicable(methodName:string, matchers): boolean {
if (this.methodName != methodName) {
return false;
}
let allValid = true;
let index: number = 0;
for (let arg of this.args) {
if (matchers[index] && !matchers[index].match(arg)) {
allValid = false;
}
index++;
}
return allValid;
}
Calling mock(TestService) results in the error 'TypeError: methodStub.hasMatchingInAnyGroup is not a function'
Thank for great library!
I found unexpected behavior with properties
ts-mockito version: 2.2.5
import {spy} from "ts-mockito";
class Foo {
counter: number;
constructor() {
this.counter = 111;
}
hello(name: string) {
return `Hello ${name} ${this.counter}!`;
}
}
const foo: Foo = new Foo();
const mockedFoo = spy(foo);
console.log(foo.hello("world"));
/*
result: Hello world function () {
var args = [];
for (var _i = 0; _i < arguments.length; _i++) {
args[_i] = arguments[_i];
}
var action = new MethodAction_1.MethodAction(key, args);
_this.methodActions.push(action);
var methodStub = _this.getMethodStub(key, args);
methodStub.execute(args);
return methodStub.getValue();
}!
*/
I have issues with mocking an async function. I assume that I can return a promise when the mocked method is called, so that the then function can be called on that promise. However when running the test, I get the following error:
1) LoginSpec
login should return a valid app token:
TypeError: Cannot read property 'then' of null
at Promise (src/login.js:1:11787)
at new Promise (<anonymous>)
at LoginService.getToken (src/login.js:1:11319)
at LoginService.<anonymous> (src/login.js:1:9410)
...
Test class:
import {expect} from 'chai';
import {suite, test} from "mocha-typescript";
import {anything, instance, mock, when} from "ts-mockito";
import {LoginService} from '../src/login';
import {RestAccess} from "../src/rest";
@suite
class LoginSpec {
private restMock = mock(RestAccess);
@test.only
public async 'login should return a valid app token'() {
// given
const ssoToken = {
access_token: 'AccessToken',
refresh_token: 'RefreshToken',
};
const promise = new Promise((resolve, reject) => {
resolve(ssoToken);
});
when(this.restMock.fetchJson('url', anything))
.thenReturn(promise);
const sut = new LoginService(instance(this.restMock));
// when
const event = {
queryStringParameters: {
code: 'ssoCode',
},
};
const appToken = await sut.login(event);
// then
const decodedToken = this.auth.decodeToken(appToken);
...
}
}
Call to mock:
private getToken(code: string): Promise<any> {
return new Promise((resolve, reject) => {
const options = {
...
};
this.rest.fetchJson('url', options).then(result => {
console.log('resolve');
resolve(result);
}).catch(err => {
reject(err);
});
});
}
Mocked method:
public async fetchJson(url: string, options: any) {
const response = await fetch(url, options);
const data = await response.json();
return data;
}
package.json
{
"dependencies": {
"@types/jsonwebtoken": "^7.2.5",
"@types/mysql": "^2.15.3",
"@types/node-fetch": "^1.6.7",
"jsonwebtoken": "^8.2.0",
"mysql": "^2.15.0",
"node-fetch": "^2.1.1"
},
"devDependencies": {
"@types/aws-lambda": "0.0.33",
"@types/chai": "^4.1.2",
"@types/mocha": "^2.2.48",
"chai": "^4.1.2",
"eslint": "^4.18.2",
"eslint-plugin-mocha": "^4.12.1",
"mocha": "^5.0.4",
"mocha-typescript": "^1.1.12",
"nyc": "^11.4.1",
"serverless-offline": "^3.18.0",
"serverless-plugin-typescript": "^1.1.5",
"ts-mockito": "^2.3.0"
},
"scripts": {
"pretest": "tsc",
"test": "nyc mocha",
"watch": "mocha-typescript-watch",
"prepare": "tsc"
}
}
How should i import functions other than mock, when, verify and instance ?
Since in the main file (lib/ts-mockito.js) only those 4 functions are exported how should import other functions like anything ? This without specifying the path to the specific file where the function is exported.
Say we have a class like so:
export default class FileLoader {
private fileToLoad: string
public constructor(fileToLoad: string) {
this.fileToLoad = fileToLoad;
this.loadFile();
}
private loadFile() {
...
}
}
I don't see any way to create a mock of the FileLoader and and instantiate it and pass parameters to the constructor.
Hey, it would be very useful to be able to name the verify statements so that when fail, its easier to identify them.
awesome library btw!!
There is a general problem with the way ts-mockito handles stubbing multiple behaviours for the single method.
As official documentation of Java Mockito states clear:
Once stubbed, the method will always return stubbed value regardless of how many times it is called.
Last stubbing is more important - when you stubbed the same method with the same arguments many times.
ts-mockito works differently. When stubbing a method with different arguments โ it affects the other stubbings of the same method.
when(mock.someMethod("some arg").thenReturn(10);
when(mock.someMethod("some other arg").thenReturn(20);
const object = instance(mock);
object.someMethod("some arg"); // returns 10
object.someMethod("some arg"); // returns null
object.someMethod("some arg"); // returns null
object.someMethod("some other arg"); // returns 20
object.someMethod("some other arg"); // returns null
object.someMethod("some other arg"); // returns null
when(mock.someMethod("some arg").thenReturn(10);
when(mock.someMethod("some other arg").thenReturn(20);
const object = instance(mock);
object.someMethod("some arg"); // returns 10
object.someMethod("some arg"); // returns 10
object.someMethod("some arg"); // returns 10
object.someMethod("some other arg"); // returns 20
object.someMethod("some other arg"); // returns 20
object.someMethod("some other arg"); // returns 20
when(mock.someMethod("some arg").thenReturn(10);
when(mock.someMethod("some arg").thenReturn(20);
const object = instance(mock);
object.someMethod("some arg"); // returns 10
object.someMethod("some arg"); // returns 20
object.someMethod("some arg"); // returns null
when(mock.someMethod("some arg").thenReturn(10);
when(mock.someMethod("some arg").thenReturn(20);
const object = instance(mock);
object.someMethod("some arg"); // returns 20
object.someMethod("some arg"); // returns 20
object.someMethod("some arg"); // returns 20
when(mock.someMethod("some arg").thenReturn(10, 20); // Compilation Error
when(mock.someMethod("some other arg")
.thenReturn(10)
.thenReturn(20); // Compilation Error
when(mock.someMethod("some arg").thenReturn(10, 20);
when(mock.someMethod("some other arg")
.thenReturn(10)
.thenReturn(20);
const object = instance(mock);
object.someMethod("some arg"); // returns 10
object.someMethod("some arg"); // returns 20
object.someMethod("some arg"); // returns 20
object.someMethod("some other arg"); // returns 10
object.someMethod("some other arg"); // returns 20
object.someMethod("some other arg"); // returns 20
Hi
I get the following error running a Angular 4 project,, what is missing?
at MethodStubSetter.webpackJsonp.../../../../ts-mockito/lib/MethodStubSetter.js.MethodStubSetter.thenReturn (http://localhost:9876/_karma_webpack_/vendor.bundle.js:37519:51)
Line causing problem:
const companyServiceMock: CompanyService = mock(CompanyService)
when(companyServiceMock.getAll).thenReturn( () => Observable.of([]) )
What are I missing ?
###When I have updated from 2.3
to 2.9
I found out that these constructions don't work anymore:
const testServiceMock = mock<TestService>(TestService);
when(testServiceMock.hello(anything())).thenReturn('a')
const testService = new TestService();
testService.hello(); // mock won't work cause I specified that it should work only when 1 argument is passed
testService.bye(); // mock won't work cause i haven't specified it at all
Ability to use anything()
for not provided parameters was great(and totally in js way), why did you took it away?(
Hey,
I noticed when I do a verify on a function that takes an array, for instance:
verify(router.navigate(['/login'])).called();
It tells me
Error: Expected "navigate(strictEqual(/login))" to be called at least 1 time(s).
If I capture the arguments and then do an expect, it does work. Somehow it removed the array around it...
If you have a class as follows
export class TestClass {
constructor(private dependency: Dependency) { }
public get myProperty(): string {
return this.dependency.getVal();
}
}
when running
let myMock = mock(TestClass);
this.dependency.getVal() will actually get executed, and fail since this.dependency will be undefined.
Occurs when generating method stubs
I am spying on an instance like this:
const runner: Runner = new Runner()
const spyRunner = spy(runner)
when(spyRunner.myFunc()).thenReturn(10000)
expect(spyRunner.now()).to.equal(10000)
The test fails with:
expected { Object (methodStubCollection, matchers, ...) } to equal 10000
It seems that invoking the method is not returning the desired result, but some transient object. Also, if I call another method that I have not setup with "when", I get the same type of object back.
What am I doing wrong?
Karma throws this exception launching tests with ts-mockito:
Error: XHR error (404 Not Found) loading http://localhost:9876/ts-mockito
Hi,
When I was trying out ts-mockito
I noticed that the instance()
method does not create different instances of the mocked Class.
For example I have a class User
with a field id
. When creating two mocked objects:
let mockedUser = mock(User);
let user1 = instance(mockedUser);
let user2 = instance(mockedUser);
if(user1.id === user2.id)
return true;
else return false;
This code yields true. Am I using the instance method in the wrong way?
Using ImmutableJS results in being unable to mock the interfaces defined. I wonder if there is a way to have these some sort of fix or integration to support it.
DeepEqualMatcher is not importing lodash which causes a runtime error.
I'm trying to unit test a token service, but I get the error:
TypeError: Cannot read property 'getAllMatchingActions' of undefined
at MethodStubVerificator.times (/Users/ryuuji3/Projects/Node/restaurant-manager/restaurant-manager-server/node_modules/ts-mockito/src/MethodStubVerificator.ts:32:63)
at MethodStubVerificator.once (/Users/ryuuji3/Projects/Node/restaurant-manager/restaurant-manager-server/node_modules/ts-mockito/src/MethodStubVerificator.ts:20:14)
at Object.<anonymous> (/Users/ryuuji3/Projects/Node/restaurant-manager/restaurant-manager-server/src/services/token.spec.ts:46:11)
at Generator.next (<anonymous>)
at fulfilled (/Users/ryuuji3/Projects/Node/restaurant-manager/restaurant-manager-server/src/services/token.spec.ts:4:58)
at <anonymous>
Here is my test:
describe('issue()', () => {
let mockRepository : TokenRepository, repository : TokenRepository
let user : User
let jwt : string
let token: Token
let service : TokenService
before(async () => {
mockRepository = mock(TokenRepository)
user = mockUser('example')
let payload : PayloadI = Token.createPayload(user)
jwt = await Token.sign(payload)
token = await Token.create(user, jwt)
when(mockRepository.register(user, jwt)).thenResolve(token)
repository = instance(mockRepository)
service = new TokenService(repository)
})
it('should call repository.register()', async () => {
await service.issue(user)
verify(
repository.register(user, jwt)
).once()
})
})
Any idea of what's going wrong?
EDIT:
It appears I should have read the documentation better.
In order to check for behaviour, rather than return, you must verify the mocker method not the instance method.
Sorry!
This is more of a question than an issue. I just started using ts-mockito and I am wondering if it is possible to "re-stub" a method to return different value? I am stubbing my method in beforeEach with a value that works for all tests but there is one particular test where I want it to return a different value. I know I can reset the mock, but that would remove ALL of the stubs, while I just want to change one. Is it possible?
With 2.2.8, I got "Maximum call stack size exceeded" error and don't have any idea where to start investigation. 2.2.7 works successful BTW.
HeadlessChrome 0.0.0 (Linux 0.0.0) SubscribeComponent should create FAILED
Failed: Maximum call stack size exceeded
RangeError: Maximum call stack size exceeded
at Mocker.webpackJsonp.../../../../ts-mockito/lib/Mock.js.Mocker.createInstancePropertyDescriptorListener home/circleci/project/front/node_modules/ts-mockito/lib/Mock.js:96:1)
at Object.get home/circleci/project/front/node_modules/ts-mockito/lib/Mock.js:48:1)
at isUnconfigurable home/circleci/project/front/node_modules/zone.js/dist/zone.js:2185:1)
at Function.Object.defineProperty home/circleci/project/front/node_modules/zone.js/dist/zone.js:2148:1)
at Mocker.webpackJsonp.../../../../ts-mockito/lib/Mock.js.Mocker.createInstancePropertyDescriptorListener home/circleci/project/front/node_modules/ts-mockito/lib/Mock.js:99:1)
at Object.get home/circleci/project/front/node_modules/ts-mockito/lib/Mock.js:48:1)
at isUnconfigurable home/circleci/project/front/node_modules/zone.js/dist/zone.js:2185:1)
at Function.Object.defineProperty home/circleci/project/front/node_modules/zone.js/dist/zone.js:2148:1)
at Mocker.webpackJsonp.../../../../ts-mockito/lib/Mock.js.Mocker.createInstancePropertyDescriptorListener home/circleci/project/front/node_modules/ts-mockito/lib/Mock.js:99:1)
at Object.get home/circleci/project/front/node_modules/ts-mockito/lib/Mock.js:48:1)
Is there any known issues related with this?
Whether there are plans to realize capture of results. I could help with the implementation. Something like that:
class Foo {
bar(a: number) {
return a + 1;
}
}
const foo = new Foo();
const mockedFoo = spy(foo);
foo(11);
captureResults(mockedFoo.bar).last(); // 12
//Or with breaking changes
capture(mockedFoo.bar).last().result; // 12
capture(mockedFoo.bar).last().args; // [11]
I found out that it's really easy to forget the call count verification:
verify(myMock.getFoo());
That will always pass and the developer will hardly notice that something is missing, since our team has a Java background. In java we could use both ways:
verify(myMock).getFoo();
verify(myMock, times(1)).getFoo();
If you call verify without anything else, it's implicit that you want to check it was called once.
I tried to find (or even thinking to implement) a tslint rule that will ensure that verify is never called without the call count verification method (once(), called(), etc), but I believe it would be better if ts-mockito would assume that a verify is always once() by default unless specified otherwise.
Hi,
I want to mock a class that uses parameters in the constructor.
That class is a JS class (no TypeScript involved) and I need to pass a value to the constructor in order to create an instance of the class.
That is basically my test so far:
// import ts-mockito
import {mock, when, instance} from 'ts-mockito';
// needed for signature
import { TradeOffer } from 'steam-tradeoffer-manager';
// needed to get ts-mockito's clazz working
const TradeOffer = require("../../node_modules/steam-tradeoffer-manager/lib/classes/TradeOffer.js");
// original constructor is TradeOffer(manager, partner, token)
let mockedTradeOffer:TradeOffer = mock(TradeOffer);
// instantiation fails because the constructor checks if "partner" is valid
let offer = instance(mockedTradeOffer);
Do you have any ideas on how I can tackle that problem? Or do we need a new feature here? ^^
Hi there. First at all many thanks for creating this amazing lib, I were looking for something like this for years.
So I was trying to use ts-mockito with proxyquire, when I realise that it might be an issue on ts-mockito when trying to spy a module (specially singleton modules) like the fs module of node.js
Apparently proxyquire/typescript (don't know who does the magic) is able to deal with the problematic of commonjs modules conversion to es modules, and the lack of .default.
When manual test doubles are created and send to proxyquire reach the other side with no problems. But when ts-mockito is used, errors like this are shown:
fs_extra_1.default.readFile is not a function
I've crated a repo to show how to use ts-mockito and proxyquire toggether and also exposing this issue. Also a better and detailed explanation of the issue, and a possible solution.
https://github.com/danyg/ts-mockito-proxyquire
When running npm test
you will see that there is a test failing which is the issue itself, as I believe is how any developer would expect to use spy to mock a module.
Hope this helps.
Hi, I'm trying to understand why we need a separate function (instance()
) to get an instance of a mocked class, since in the original (Java) version of mockito, mock()
returns an instantiated object.
There is some technical limitation in Typesctipt?
It seems like I can't verify objects getting passed in.
// Using instance in source code
foo.getBar({ foo: "bar" });
// Explicit, readable verification
verify(mockedFoo.getBar({ foo: "bar" })).called();
Will fail
I see that this is not supported yet:
'Argument of type 'typeof AbstractClass' is not assignable to parameter of type 'new (...args: any[]) => AbstractClass'.
Cannot assign an abstract constructor type to a non-abstract constructor type.'
Can this be supported in TypeScript or not yet possible?
Thanks!
I started just started using this library. And had some problems getting starting, because I havent seen that instance(...)
is needed.
I would expect that mock(...)
would return some Generic type Mock<T>
that will be used by the instance(...)
method.
Then the compiler would throw an error.
When mocking a class that contains a method, that internally calls toString()
I get the following error when the toString()
method is invoked on the mocked instance itself.
TypeError: methodStub.hasMatchingInAnyGroup is not a function
at Mocker.webpackJsonp.../../../../ts-mockito/lib/Mock.js.Mocker.getMethodStub home/dev/src/ui/~/ts-mockito/lib/Mock.js:183:1)
at Proxy.<anonymous> home/dev/src/ui/~/ts-mockito/lib/Mock.js:115:1)
I guess that is related to the same problem like in #28
When I was debugging the ts-mockito code, I could see, that https://github.com/NagRock/ts-mockito/blob/master/src/utils/MockableFunctionsFinder.ts returned a positive match on my dummy() function that contains the toString()
invocation and defines the toString()
method as a mockable function, even though this is not needed / required.
This is a jasmine test example I used to reproduce the error:
import {instance, mock} from "ts-mockito";
describe("toString", () => {
it("should not break on toString", () => {
const dummyMock: Dummy = mock(Dummy);
const dummyInstance: Dummy = instance(dummyMock);
dummyInstance.toString();
});
});
export class Dummy {
public dummy(): void {
window.toString();
}
}
This behavior causes problems in our test setup, where jasmine wants to create a human readable error message, in case an assertion failed. However if the expected object contains a mock of a class like the Dummy class on top with a toString()
method in the body of a function, it will fail and therefore hide the actual failed expectation.
Weirdly enough when i comment out the window.toString()
line the MockableFunctionsFinder.ts
still matches the given toString()
function. As stated in the comment of that class, it is greedy but it even captures comments and so on.
Indented behavior is last stubbing is more important and should be used.
when(mock(mockObject.method())).thenReturn(false);
when(mock(mockObject.method())).thenReturn(true);
Return false.
it should return last stubbing value, true.
when(mock(mockObject.method())).thenReturn(false);
reset(mockObject);
when(mock(mockObject.method())).thenReturn(true);
Workaround calling reset before next stubbing duplicate, but would be great be default simpler usage and does not reset the whole object.
Regards
Hi guys, I trying use ts-mockito for mock ngrx store.
With "plain" selectors its works good:
when(storeMock.select(getCurrentTabId)).thenReturn(Observable.of('') as any);
But if selector with input params (like: getCardDetailsById('123')
) then I have some problems with mock:
when(storeMock.select(getCardDetailsById('123'))).thenReturn(Observable.of({}) as any);
- its doesn't work (test runs but failed because mock didn't triggered)
And sure, I can use anything()
, but I have several test cases with this "problem" in one test, so can't use anything()
and try find a way for solve it.
I'm trying to do both a capture and return on the same mock, but I can't figure out how to set it up. This is my attempt so far:
const mockedDS = mock(MyDataService);
const whenCall = when(mockedDS.update(anything(), anything());
whenCall.thenReturn("OK");
const firstCaptor = new Captor<Array<Employee>>();
const secondCaptor = new Captor<TimePeriod>();
whenCall.thenCapture(firstCaptor, secondCaptor);
It seems that I can only do one or the other? Depending on whether I call thenCapture
before thenReturn
or vice versa it will only capture OR return the value.
Btw. What I'd really like to write is this;
const mockedDS = mock(MyDataService);
const firstCaptor = new Captor<Array<Employee>>();
const secondCaptor = new Captor<TimePeriod>();
when(mockedDS.update(anything(), anything())
.thenCapture(firstCaptor, secondCaptor);
.thenReturn("OK");
...but both thenReturn
and thenCapture
returns void
Hello all. Thank you for this library: it has made unit testing my Typescript code much much easier :).
I had a question about the types of the matchers. I recently made an interface-breaking change in my code, but my tests did not have the compilation errors I expected. The reason is that although ts-mockito will type check normal expectations, once I wrap it in a deepEqual
matcher, the matcher returns an any
. Here is a simplified example:
abstract class Area {
public abstract toString(): string;
}
class ZipCode extends Area {
constructor(private zipCode: string) { super(); }
public toString() { return this.zipCode; }
}
class CityState extends Area {
constructor(private city: string, private state: string) { super(); }
public toString() { return `${this.city}, ${this.state}`; }
}
class WeatherClient {
public getWeather(area: Area): Promise<string>;
}
const client = mock(WeatherClient);
when(client.getWeather(deepEqual('81547'))).thenReturn(Promise.resolve('rainy'));
I would expect the when
line to throw a type error, because I'm passing in a string, but the deepEqual
changes it to any
.
The relevant line is here:
https://github.com/NagRock/ts-mockito/blob/master/src/ts-mockito.ts#L108
Is it possible to redefine deepEqual
to something like:
export function deepEqual<T>(expected: T): T
?
Thank you!
in #16 were proposed fluent API for capturing arguments and setting return value. But this API is in conflict with #12
So after conversation with @michalstocki we thought about such solutions:
when(someObject.doSomething(anything())).thenReturn(3).thenCapture(captor);
- but after implementing #12 this API would be illogical because we will be able to define more returning values with fluent API e.g. when(someObject.doSomething(anything())).thenReturn(3).thenReturn(4).thenReturn(5).thenCapture(captor);
- thenReturn call order will have matter. So thenCapture does not fit here.verify(someObject.doSomething(captor.capture()));
- similar to JavaMockito version, but we decided that using verify
API function is not best solution, maybe this will be added as option to be more compatible with Java versionwhen(someObject.doSomething(anything())).thenReturnAndCapture(3, captor)
- this not looks nice, and arguments type checking will be impossible.when(someObject.doSomething(anything(firstCaptor))).thenReturn(3);
- on first sight looks nice, but capturing arguments should not have any conditions while here we can define e.g. between(3, 4, capture)
- and this looks badcapture(someObject.doSomething(captor));
- this looks best at all, we do not use conditions, we strictly says that we want to capture argumentsThe Basic example in the README shows:
let mockedFoo:Foo = mock(Foo);
but the the verify has:
verify(fooMock.getBar(3)).called();
fooMock is not defined.
Hey! First of all I want to thank you for the awesome Mocking Frameworks that you made.
In package.json @types/lodash
is referenced as a direct dependency and its loaded automatically in the ts-mockito
depended projects.
It wouldn't be a problem if everyone would use lodash
but that's not the case. At the compile the variable _
enters in conflict with other libraries that define the same variable name.
Resulting in a nasty, not so easy to debug :
Error "Duplicate identifier '_'"
As the users of this framework use only the compiled .js with the typing definitions the @types/lodash is not required into dependencies.
It could be really nice to have a following verification options:
verify(classA.someMethod(someArg)).calledBefore(classB.someMethod(otherArg));
verify(classA.someMethod(someArg)).calledAfter(classB.someMethod(otherArg));
or maybe different syntax:
const classACall:(someType?) = verify(classB.someMethod(otherArg)).called();
verify(classA.someMethod(someArg)).calledBefore(classACall);
However I'd prefere the first syntax.
import * as mockito from "./ts-mockito";
export default mockito;
The ts-mockito module requires itself to export itself as default. I find this rather confusing, and it causes an error when bundling the module using rollup with rollup-plugin-commonjs ("A module cannot import itself
"). Isn't there are a cleaner solution to provide a default export?
The instance()
call for a mock returns always a new Proxy
class instance (when supported). In that case e.g. a verify()
does not recognise the parameter when an instance of a mock is used.
This is a different behaviour compared to the result of an instance()
call when Proxy
is not supported by the browser.
A simple (somehow constructed) example:
const fooMock = mock(Foo);
const fooInstance = instance(fooMock);
// ... some code later
when(fooMock.clone(instance(fooMock))).thenReturn(fooInstance);
/*
the "when()" does not match because a new Proxy class will be
returned from "instance()" for each call (works in an older
browser not supporting Proxy)
*/
fooInstance.clone(fooInstance);
Although the example is quite constructed, the instance()
method should not change its behaviour depending on the environment.
It looks like getters and setters are not currently supported. Is there a plan for this in the future?
Example:
class LocationUtility {
public get routeParams(): any {
return {};
}
}
The below code will result in an error: "Uncaught TypeError: Cannot read property 'proof' of undefined"
let location = mock(LocationUtility);
instance(location).routeParams.id
first of all, great library! simple and powerful.
I just want to mock a class and return a string on a precise field, but I'm getting an error on a precise case.
I'm wondering if it's a bug or I'm doing it wrongly?
WORKING Sample code
export class DtoData {
data: string;
}
const mockData = mock(DtoData );
when(mockData.data).thenReturn('test');
BREAKING Sample code because of the imGonnaBreakTheDto() method declared (but not used) in the class
export class DtoData {
data: string;
imGonnaBreakTheDto() {
return this.data && this.data;
}
}
const mockData = mock(DtoData );
when(mockData.data).thenReturn('test');
this gives me 'Cannot read property 'add' of undefined' on the when because it finds 'data' as function instead of MethodToStub type when using the thenReturn.
Funny thing is that if I use only
imGonnaBreakTheDto() {
return this.data;
}
it works.
Hi folks,
are there any plans to support mocking of static methods?
Cheers
Ingo
Hey guys,
Any plan on supporting spy in the same style as java mockito does? the library is fantastic by the way
Kind Regards
Gabriel
Great framework! I noticed though that verify
doesn't properly seem to check for different number of arguments/missing arguments.
class Foo {
bar(a?: number, b?: number) {}
}
let mockFoo = mock(Foo)
let foo = instance(mockFoo)
foo.bar(5)
verify(mockFoo.bar(5, 6)).called()
This should throw a verification error but doesn't.
Hi,
I really like ts-mockito, so thank you for this library. Following this guide on stubbing Observables in angular 2, it seemed straightforward to do a similar thing with mocks.
Consider a service with a method, getObservable()
, that returns an Observable<SomeType>
, where SomeType
is simply a TS interface. How would one setup a mocked object to override this method?
First I created some mocked data of type SomeType
:
const mockedData: SomeType = {foo: 'bar'}
And then I stub the method call
when(mockedService.getData('1')).thenReturn(Observable.of(mockedData))
But this gives a runtime error (compiler has no problem with it...)
TypeError: Cannot read property 'methodStubCollection' of null
at http://localhost:9876/_karma_webpack_/webpack:/C:/Users/xbbl2q8/Desktop/development/ears-ui/ewh-earsui-angularui/node_modules/ts-mockito/lib/MethodStubSetter.js:18:1
at Array.forEach (<anonymous>)
at MethodStubSetter.webpackJsonp.../../../../ts-mockito/lib/MethodStubSetter.js.MethodStubSetter.thenReturn (http://localhost:9876/_karma_webpack_/webpack:/C:/Users/xbbl2q8/Desktop/development/ears-ui/ewh-earsui-angularui/node_modules/ts-mockito/lib/MethodStubSetter.js:17:1)
at Object.<anonymous> (http://localhost:9876/_karma_webpack_/webpack:/C:/Users/xbbl2q8/Desktop/development/ears-ui/ewh-earsui-angularui/src/app/shared/services/activiti/activiti.handler.spec.ts:82:37)
at ZoneDelegate.webpackJsonp.../../../../zone.js/dist/zone.js.ZoneDelegate.invoke (http://localhost:9876/_karma_webpack_/webpack:/C:/Users/xbbl2q8/Desktop/development/ears-ui/ewh-earsui-angularui/node_modules/zone.js/dist/zone.js:392:1)
at ProxyZoneSpec.webpackJsonp.../../../../zone.js/dist/proxy.js.ProxyZoneSpec.onInvoke (http://localhost:9876/_karma_webpack_/webpack:/C:/Users/xbbl2q8/Desktop/development/ears-ui/ewh-earsui-angularui/node_modules/zone.js/dist/proxy.js:79:1)
at ZoneDelegate.webpackJsonp.../../../../zone.js/dist/zone.js.ZoneDelegate.invoke (http://localhost:9876/_karma_webpack_/webpack:/C:/Users/xbbl2q8/Desktop/development/ears-ui/ewh-earsui-angularui/node_modules/zone.js/dist/zone.js:391:1)
at Zone.webpackJsonp.../../../../zone.js/dist/zone.js.Zone.run (http://localhost:9876/_karma_webpack_/webpack:/C:/Users/xbbl2q8/Desktop/development/ears-ui/ewh-earsui-angularui/node_modules/zone.js/dist/zone.js:142:1)
at Object.<anonymous> (http://localhost:9876/_karma_webpack_/webpack:/C:/Users/xbbl2q8/Desktop/development/ears-ui/ewh-earsui-angularui/node_modules/zone.js/dist/jasmine-patch.js:104:1)
Anyone ever seen something similar?
Also posted on SO (https://stackoverflow.com/questions/47035242/angular-observable-stubbing-doesnt-work-in-ts-mockito)
Dropping into the source, it looks like MethodStubSetter.js
is not setting_this.methodStub
when called via the Observable.of() method.
When I try to create a mock of the Restify Response,
import { mock } from 'ts-mockito';
import { Response } from 'restify';
const response: Response = mock(Response);
I get the error:
Type 'Response' is not assignable to type 'Response'. Two different types with this name exist, but they are unrelated.
Property 'header' is missing in type 'Response'.
Is there any way to solve this issue?
thx
import { instance, mock, when } from 'ts-mockito'
import expect from 'ceylon'
export default class TestClass {
withOptionalParameter(foo: string, bar?: string) {
return foo + bar
}
}
describe('using a ts-mockito mock of TestClass ->', () => {
const mockCreator = mock(TestClass)
when(mockCreator.withOptionalParameter('a')).thenReturn('aa')
when(mockCreator.withOptionalParameter('b', 'c')).thenReturn('bcbc')
const mockInstance = instance(mockCreator)
describe('withOptionalParameter', () => {
it('should work!', () => {
expect(mockInstance.withOptionalParameter('a')).toEqual('aa')
expect(mockInstance.withOptionalParameter('b', 'c')).toEqual('bcbc')
})
})
})
This results in a "TypeError: Cannot read property 'match' of undefined" when running the test.
If the first when
call is change to have two parameters like the second one, ie when(mockCreator.withOptionalParameter('a', 'a')).thenReturn('aa')
then the test works. So apparently something goes wrong if you provide multiple when
matchers with different numbers of parameters.
Is it currently possible to mock field values? Unfortunately, not everything is using get
and set
functions and exposing the field instead.
export class Foo {
isBar: boolean;
}
let fooMock = mock(Foo);
when(fooMock.isBar).thenReturn(false);
throws the error:
TypeError: Cannot read property 'methodStubCollection' of undefined
at MethodStubSetter.thenReturn (webpack:/~/ts-mockito/lib/MethodStubSetter.js:18:1)
at Object. (webpack:/fooTests.ts:25:33)
Is there a cool way without using:
let inst = instance(fooMock);
inst.isBar = false;
??
If not, are you open for a pull request with an suggestion?
If yes does it have to be similar to the java mockito way of doing it (if there is one)?
I have the following inheritance:
abstract class A {
protected protectedField:SomeType;
public setProtected(type:SomeType):void {
this.protectedField = type;
}
}
class B extends A {
public someMethod():void {
this.protectedField.doSomething();
}
}
And I try to test:
it('does something', () => {
// given
const mockType:SomeType = mock(SomeType);
const b = new B();
b.setProtected(instance(mockType));
// when
b.someMethod();
// then
verify(mockType.doSomething()).once();
});
Then I unfortunatelly get the following error:
Expected "doSomething()" to be called 1 time(s). But has been called 0 time(s).
times
once
When I can see the reset
function, I expect them to reset not only the calls which were recorded, but also the mocked functionality of all the methods.
I expect the following test to pass:
describe('Mock resetting', () => {
it('should reset a value configured to be returned', () => {
// given
const myClassMock = mock(MyClass);
when(myClassMock.methodB('some string')).thenReturn('other string');
const myClass = instance(myClassMock);
reset(myClassMock);
// when
const result = myClass.methodB('some string');
// then
expect(result).to.not.equal('other string');
});
});
class MyClass {
public methodB(someArgument:string):string {
return `provided value: ${someArgument}`;
}
}
Here is a link for the test within the configured project:
https://github.com/michalstocki/ts-mockito-example/blob/master/test/spec/extension/resetting/mock-resetting.spec.ts
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.