sinon - spy on toString method - node.js

In my file, I have something like this:
if(somevar.toString().length == 2) ....
How can I spy on toString from my test file? I know how to spy on things like parseInt with:
let spy = sinon.spy(global, 'parseInt')
But that doesn't work with toString since it's called on the value, I tried spying on Object and Object.prototype, but that doesn't work either.

Related

Calling OCMStub and OCMReject on the same method

I've been attempting to write some fail fast tests using OCMReject. However I've found that if OCMStub is used in conjunction with OCMReject, this test will pass
id _mockModel = OCMProtocolMock( #protocol( CTPrefModelProtocol));
//It doesn't seem to matter what order these two are in, the test behaves the same
OCMStub([_mockModel getPreferences]);
OCMReject([_mockModel getPreferences]);
[_mockModel getPreferences];
Even though it should clearly fail because I'm calling the function that I've set in the OCMReject method.
I realise I can just stub getPreferences whenever I'm expecting a result from it and remove it from this test, but largely that means if I've set a stub on getPreferences in my setUp method, any test that calls OCMReject([_mockModel getPreferences]) will just be ignored.
Why am I not able to use OCMStub and OCMReject together? Is it because OCMStub alters getPreferences somehow and as a result whenever I call this method, it actually calls some other method instead?
So apparently I can't read. Reading through the OCMock 3 Documentation, under the limitations heading 10.2
Setting up expect after stub on the same method does not work
id mock = OCMStrictClassMock([SomeClass class]);
OCMStub([mock someMethod]).andReturn(#"a string");
OCMExpect([mock someMethod]);
/* run code under test */
OCMVerifyAll(mock); // will complain that someMethod has not been called
The code above first sets up a stub for someMethod and afterwards an
expectation for the same method. Due to the way mock objects are
currently implemented any calls to someMethod are handled by the stub.
This means that even if the method is called the verify fails. It is
possible to avoid this problem by adding andReturn to the expect
statement. You can also set up a stub after the expect.
I suspect this same limitation exists for OCMReject as well. Hopefully this helps equally blind people like myself. A link to the documentation for the lazy.

How to test the content of callback of method

I might not be getting something but I am trying to test the callback content of a method but without calling the method.
The function I am trying to test
functionToSkip(param1, param2, function(arg1, arg2){
if(arg1){
// Do some things here
} else {
// Do other things here
}
}
What I am trying to do is to test the content of the callback function with differents args values that I can change in the tests and the parameter of the functionToSkip can be anything.
All I successfully did is to skip the call of the function but I cannot call the callback method.
I did stub the function to skip and even trying to give values to the callback method but there is not any logs showing.
var spy = sinon.stub(Class, "functionToSkip").calledWith(param1, param2, ("arg1","arg2"))
The main method that is calling the stubbed function works since I can see the logs prior of the function when I call it in the tests.
First of all, if functionToSkip is an instance method on Class, it will be a property on Class.prototype, not Class itself. In order to stub, you can do one of two things:
Create an instance, and create the stub:
instance = new Class(/*costructor arguments*/)
var stub = sinon.stub(instance, 'functionToSkip')
Or, stub on the prototype:
var stub = sinon.stub(Class.prototype, 'functionToSkip');
In the second case, since class prototypes are global state, I'd recommend restoring it-- preferably in something like mocha afterEach to ensure it gets cleaned up whether your test is successful or not. This way it doesn't screw with other tests in your run:
stub.restore()
Between the two, though, I recommend the first approach.
Next up... If you want to make assertions on the content of calls, the firs thing you'll probably want to do is assert that it was in fact called with the signature you're looking for:
sinon.assert.calledWith(stub, sinon.match.any, sinon.match.any, sinon.match.func)
The any matcher allows any value, and the func matcher requires a func. After that, you can obtain the callback function like so:
var cb = stub.firstCall.args[2]
And invoke it like so:
cb('arg1', 'arg2');
As to what assertions you'd do after invoking the callback function-- I'd have to know more about what you're trying to test about it to make recommendations.

How can I check if an anonymous function has been called with NSubstitute?

I want to check if an anonymous function has been called with NSubstitute. A method in a class I have takes a Func<> parameter, and I want to make sure this parameter is called (or not called). I have tried the following, but it does not seem to work:
var spy = Substitute.For<Func<string, int>>();
MyClass.DoSomething(spy);
spy.Invoke(Arg.Any<string>()).Received();
This however throws an exception:
NSubstitute.Exceptions.NullSubstituteReferenceException : NSubstitute extension methods like .Received can only be called on objects created using Substitute.For<T>() and related methods.
Try replacing
spy.Invoke(Arg.Any<string>()).Received();
with
spy.Received().Invoke(Arg.Any<string>());
There's no difference if your production code calls the func via spy.Invoke() or via spy(). But the test won't succeed, if your code calls BeginInvoke. But I think that shouldn't be a problem, because you should know in advance if a test for Invoke or BeginInvoke is needed.

Why is a method called from the Expect() statement?

I am trying to set an expectation on a Mocked object to find out if the method was called as expected.
I use the following code to achieve it.
//// Create a mocked object(arrange)
A controller = MockRepository.GenerateMock<A>();
someObject.Stub(x => x.Resolve(typeof(A))).Return(controller);
//// Act i.e. call the target function where the controller is created
this._target.InvokePrivateMethod("OnTargetUpdated", false, this, eventArgs);
//// Assert
controller.AssertWasCalled(x => x.UpdateTarget(targetInfo2), o => o.Repeat.Once());
However, when i try to assert if the "UpdateTarget()" was called the flow goes into the code of the method. I simply want to check "If the method was called" and not "call the method".
As method UpdateTarget() is non-virtual then Rhino Mock can't intercept call to it.
That's why the real method is executed instead.
See details e.g. in this question.
To get your test working you need to make mocked method virtual. Or even better if you use interface here instead of class.

RhinoMocks - Fetching parameters of called functions

Using RhinoMocks - can I fetch the parameters of a called function? I mean; can I get some of the unknown parameters from the function call out?
I have a mock, and I expect some function to be called on this. I know one of the parameters, but the other one is unknown as this comes from the class that uses the mock and calls a function on it. More specificly - in this case - the unknown argument is a lambda function. This is a callback function that is supposed to be called when the function is finished executing. As the mock prevents the callback from being called I want to fetch it and call it myself.
So; I want to check that the function was called. I want to make sure some of the arguments were the expected ones. And I want to get out the unknown arguments to do some operations on them afterwards.
Assuming both arguments are ints (for simplicity) I'd like to do something like this:
int unknownInt;
_fakeSomething.AssertWasCalled(factory => factory.Foo(1, out unknownInt));
// then play around with unknownInt..
Can this be done? I see there is an Arg.Out, but couldn't quite make it work..
Note: Updated the question as it seemed to be misleading.
Arg<string>.Matches(arg => you got the argument here...);
UPDATE:
To fetch the second argument made on the first call of the Foo method on _fakeSomething:
string someArg = null;
var args = _fakeSomething.GetArgumentsForCallsMadeOn(
x => x.Foo(0, 0),
x => x.IgnoreArguments()
);
var int = (int)args[0][1];
Not sure if it can be done, but testing like that can result in unreliable tests, as you don't know the actual paramter that was passed in.
If possible, test on explicit data. If you f.eks pass in null instead of a real value your test will likely pass for the wrong reason.
Testing with Arg.Is.Anything should be done carefully and when you truly don't care about the parameter, such as in AssertWasNotCalled.

Resources