Does verifying the mock is need in minitest - minitest

I'm reading the mocking capability of minitest.
require "minitest/autorun"
mock = MiniTest::Mock.new
mock.expect(:use_any_string, true, [String])
mock.use_any_string("foo")
## mock.use_any_string(1)
## MockExpectationError: mocked method :use_any_string called with unexpected arguments [1]
## I do not understand the purpose for this
mock.verify
So I do not understand the purpose of using mock.verify since the trying to pass any another type(to use_any_string) other than String result in mock expectation error.
So why should one use assert mock.verify then?

You are right, you cannot set anything else to the configured mock, but if your mock is not called at all, then you can find out with mock.verify. So if your method under test should call the mocked method, you should verify that it was called at all.

You are correct, mock.expect(:use_any_string, true, [String]) will cause the test to fail if the expected call is not made on the mock.
However using mock.verify depends on how you compose your test. In your example you are explicitly calling the method you are testing with mock.use_any_string("foo") so there is no need to also call mock.verify.
You could get into a scenario where you are not making this call explicitly, or are expecting the mock to have had calls made at a certain time. These scenarios would take advantage of mock.verify calls.
(Another note, minitest has recently introduced assert_mock which can be used instead of mock.verify)

Related

Mockito verify doesn't match multiple stub

It seems that, when I use thenReturn like this:
when(abc.call()).thenReturn(a).thenReturn(b),
I expect:
verify(abc, times(2)).call()
instead, the method seems only get called once, I am a little confused(my test work as expected, the mock seems return the value I expected), but for the invocation times, I don't know if I am getting the wrong result, or it's a expected behavior of the Mockito?
when() is mocking the abc.call() method which has to produce a certain return type. If the method is called once, it will return the value also once, so the stubbing for method invocation is done only once hence the verify only recognizes one call.
You need to customize your function so that the stub(abc.call()) gets called more than once.
You can follow this thread for implementing multiple stubs

Jest: Find out if current module is mocked during runtime

Is there a way i can find out during runtime if a module is mocked via jest?
Since mocked modules get required normally and therefore the code gets executed (as seen here: jest module executed even when mocked
We need this because we have checks on top of each file to fail early when a mandatory environment variable is not set, which causes our tests to fail even if the module is mocked.
if (!process.env.SOME_ENV) {
throw new Error(`Mandatory environment variable 'SOME_ENV' not set`)
}
We are looking for something like this:
if (!process.env.SOME_ENV && utils.isNotMocked(this)) {
throw new Error(`Mandatory environment variable 'SOME_ENV' not set`)
}
where utils.isNotMocked(this) is the magic function which checks if the module is currently mocked.
As #jonrsharpe mentioned, it is typically not desirable that software can distinguish whether it is under test or not. This means, you will probably not find the feature you are hoping for in any mocking framework. Moreover, there may be more fundamental problems to provide such a feature, because you might have mixed test scenarios where for some test cases an object of the mocked class is used, and for other test cases an object of the original class is used.
Since you are using the early exit mechanism as a general pattern in your code, as you describe: What about creating a library function for this check - which then again can be doubled during testing such that in that case the function does not throw?

Jest how to assert that function is not called

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);

How can I use Groovy's mock.interceptor package to mock an objects constructor?

In my attempt to mock an object in Groovy using the mock.interceptor package:
def mock = new MockFor(TheClass);
mock.demand.theMethod{ "return" }
mock.use {
def underTest = new TheClass()
println underTest.theMethod()
}
The problem I have is when creating TheClass() in the use{ block, it uses the actual constructor which, in this circumstance, I'd rather it not use. How can I create an instance of this class so I can test the method I do care about, theMethod, without needing to use the constructor?
Using EasyMock/CE, mocks can be made without using the constructor, but am curious how to achieve that in Groovy.
I recently saw a presentation by the author of GMock and it has some hooks to allow "constructor" mocking which I think is what you are after.
e.g.
def mockFile = mock(File, constructor('/a/path/file.txt'))
This library differs from that "built in" to groovy, however it looked very well written, with some thought put into the kinds of things you want to mock and more importantly the error messages you would get when tests should fail.
I think this is what you are after. I would say use constructor mocking with care - it could be a smell that you should inject a Factory object, but for some things it looked to work well.
You can use the interceptConstruction flag when calling MockFor, see
MockFor.

Is verify called automatically on Groovy's MockFor

According to the javadocs, Groovy's MockFor object always ends with a verify. Its StubFor docs say calling verify is up to the user. I read that as saying that verify will automatically be called on the MockFor object. However, in looking at the groovy samples that use MockFor on a Java object (http://svn.codehaus.org/groovy/trunk/groovy/groovy-core/src/test/groovy/mock/interceptor/MockForJavaTest.groovy), they call verify explicitly. I've found in my tests that I need to do the same. Are the docs just incorrect or maybe I'm misunderstanding. Any help would be appreciated.
thanks,
Jeff
According to the docs (http://groovy.codehaus.org/Groovy+Mocks), the instance-style mocking that's invoked with the proxyInstance() method (for Groovy) or the proxyDelegateInstance() method (for Java, as in the example you referenced) does indeed require an explicit call to verify.
It's the class-style mocking -- which is invoked by passing in a closure to the .use method -- that does an implicit verify. That's the case for both Mock and Stub.
My understanding of the difference between a Mock and a Stub is that it's a matter of what gets verified when verify is called, not how it's called. A mock validates that events happen in a certain order while a stub only cares that events happen a certain number of times.

Resources