In my NodeUnit tests, I have such a piece of code:
exports['aTest'] = function(test){
...
var functionResult = test.doesNotThrow(aFunction(aParam));
...
}
But functionResult is undefined after the call to doesNotThrow(...)
Why does test.doesNotThrow() not return the result of the function call?
That would be quite elegant.
It doesn't return anything as shown in the source code, this is because nodeunit relies on AssertionError to determine if a suite succeeded or not, as you could see here
Why would you want it to return something, what return value would you expect?
The purpose of the library is to test your assertions. It should not return a value since that would mean giving you info to do something with that value, instead, when an assertion throws you will get a console message saying that your tests got broken. I believe this is a good approach.
Your goal is to be notified when something brokes, relying on the library to tell you what broke, not to delve yourself into the details, that is why I believe the author chose this way.
Related
In Jest there are functions like tobeCalled or toBeCalledWith to check if a particular function is called.
Is there any way to check that a function is not called?
Just use not.
expect(mockFn).not.toHaveBeenCalled()
See the jest documentation
not did not work for me, throwing a Invalid Chai property: toHaveBeenCalled
But using toHaveBeenCalledTimes with zero does the trick:
expect(mock).toHaveBeenCalledTimes(0)
Recent versions of Jest (22.x and onwards) collect quite decent statistics of mock functions calls, just check out their docs.
The calls property shows you the number of calls, the arguments passed to the mock, the result returned out of it and whatnot. You can access it directly, as a property of mock (e.g. in a way how #Christian Bonzelet suggested in his answer):
// The function was called exactly once
expect(someMockFunction.mock.calls.length).toBe(1);
// The first arg of the first call to the function was 'first arg'
expect(someMockFunction.mock.calls[0][0]).toBe('first arg');
// The second arg of the first call to the function was 'second arg'
expect(someMockFunction.mock.calls[0][1]).toBe('second arg');
I personally prefer this way as it gives you more flexibility and keeps code cleaner in case if you test for different inputs that produce a different number of calls.
However, you can also use shorthand aliases for Jest's expect since recently (spy matchers aliases PR). I guess .toHaveBeenCalledTimes would suit fine here:
test('drinkEach drinks each drink', () => {
const drink = jest.fn();
drinkEach(drink, ['lemon', 'octopus']);
expect(drink).toHaveBeenCalledTimes(2); // or check for 0 if needed
});
In rare cases, you might even want to consider writing your own fixture that'd do the counting. It could be useful if you're heavy on conditioning or working with state, for example.
Hope this helps!
Please follow the documentation from jest:
https://jestjs.io/docs/en/mock-functions#mock-property
All mock functions have this special .mock property, which is where data about how the function has been called and what the function returned is kept. The .mock property also tracks the value of this for each call, so it is possible to inspect this as well: [...]
These mock members are very useful in tests to assert how these functions get called, instantiated, or what they returned:
// The function was called exactly once
expect(someMockFunction.mock.calls.length).toBe(1);
Or...
// The function was not called
expect(someMockFunction.mock.calls.length).toBe(0);
I'm writing unit test for my project. But I always meet this problem
Cannot read property 'be' of undefined.
I have a test suite called model-xxx, and I wanna try each method in this model. So each method I write a sub test suite in model-xxx. like this:
enter image description here
And each method is related with mongoose, so I hope these sub suite will be async. so each method I write done() in before and after and it
but none of these suite passed. error like this:
enter image description here
and like this:
Cannot read property 'not' of undefined.
why this occurs? does this mean something wrong with my should.js? but it doesn't make sense
hope for solutions.
Chai's should is a function that needs to be called before you can use should-style assertions:
var should = require('chai').should();
See the documentation.
Still learning code contracts. When I create a small test, I get the following message from the checker: CodeContracts: Invoking this method will always lead to an error. If this is wanted, consider adding Contract.Requires(false) to document it.
I don't understand what it is try to tell me. How would I add Contract.Requires(false) to this example so the warning is not shown?
This is the code. Note that this is a contrived example solely for the purpose of learning CC.
void DoSomething(object test) {
Contract.Requires(test != null);
MessageBox.Show(test.ToString());
}
void InvokeDoSomething() {
DoSomething(null);
}
Code Contracts have discovered that you
Require a parameter to a method to never be null
Literally call it with null
CC is basically telling you that your code will always fail. The contract seems fine, but your call is bad. The solution is of course not to add Contract.Requires(false) but to not call the method with null.
Unfortunately, many Template Haskell functions have absolutely no documentation at all. One such function is report. It takes a Bool and a String, and produces a compilation error with the specified string as the error message. Does anybody have any clue what the hell the Bool is for? As best as I can tell, either value does exactly the same thing...
If the Bool is True, an error is reported; if it is False, a "warning" is reported, meaning that the template code will continue to run to collect more "warnings."
Looking at the source code, report calls qReport, which is a method of some class called Quasi. This method actually has some damned documentation - though only a tiny snippet. I quote:
Report an error (True) or warning (False) ...but carry on; use fail to stop
So it seems to make my TH splice crash with an appropriate error message, I just need to call fail instead. Hopefully this information will be useful to anyone else trying to figure that out...
Wanted but not invoked: However, there were other interactions with this mock:
This is a mockito error you would catch when trying to verify the invocation on an object on specific method, but what happens is you have interacted with other method of that object but not the one mentioned.
If you have an object named CustomerService and say it has two methods named saveCustomer() and verifyExistingCustomer(),
and your mockito looks something like verify(customerService, atleast(1)).verifyExistingCustomer(customer), but in your actual service you called the saveCustomer() at least one.
Any idea how to resolve this ?
From what you are describing, it looks like you are telling your mocks that you are expecting verifyExistingCustomer() to be called but you are not actually calling it.
You should probably look at your test design, specifically ensuring that you can (via mocking) isolate your tests to test each method individually.
If there is something in your code that decides whether to call saveCustomer() or verifyExistingCustomer() then you should try to mock the data that the code inspects so that you can test each individually.
For example if your code looked like this:
if (customer.getId() == 0) {
saveCustomer(customer);
} else {
verifyExistingCustomer(customer);
}
Then you could have two separate tests that you could isolate by setting a zero value and non-zero value for the id in customer.
If you'd like to share your code I could probably give you a better example.