Does OCMockito reset invocation count after a verify() call? - ios

Here is the pseudocode of my unit test:
int invocationCount
given(mock).willDo {
invocationCount++
return value
}
doSomeProcessing()
verify(mock)
doSomeMoreProcessing()
verifyCount(mock, 2)
At this point, invocationCount == 2, as expected. However, verifyCount fails, saying it was only called once. In addition, if I exclude the first verify call, the test passes as expected. It might be relevant to note that each verify call is capturing a new argument for assertion later.
My question is this: when the first verify() is called, is the mock's invocation count reset? If this is not the case, what could be happening?

Yes, verification only counts the matches since the last verification.
Further discussion can be found here: https://github.com/jonreid/OCMockito/issues/116

Related

Why is Dafny allowing uninitialized return result?

In this method:
datatype Results = Foo | Bar
method test() returns (r:Result)
{
}
Dafny verifies OK and test() returns Foo. Which is technically correct (it does return a value of the correct type) however I was expecting Dafny to complain that the result has not been set by the method itself. What test() is doing is similar to doing:
return;
in a C function that is supposed to return an int.
Is there a way to make Dafny verify that a methods results are always set before the method returns?
The flag you want is /definiteAssignment:2:
/definiteAssignment:<n>
0 - ignores definite-assignment rules; this mode is for testing only--it is
not sound
1 (default) - enforces definite-assignment rules for compiled variables and fields
whose types do not support auto-initialization and for ghost variables
and fields whose type is possibly empty
2 - enforces definite-assignment for all non-yield-parameter
variables and fields, regardless of their types
3 - like 2, but also performs checks in the compiler that no nondeterministic
statements are used; thus, a program that passes at this level 3 is one
that the language guarantees that values seen during execution will be
the same in every run of the program
This is what Dafny says on your code says with that flag:
test.dfy(5,0): Error: out-parameter 'r', which is subject to definite-assignment rules, might be uninitialized at this return point

Matching a method signature with a unknown parameter in a mocked class

I have this method:
Future<Either<Failure, WorkEntity>> updateWorkEntity({int id, String title, TimeType timeType, int times, DateTime executed})
that is being called like this:
repository.updateWorkEntity(id: workEntity.id, executed: DateTime.now())
the id I can control in a test, but the "DateTime.now()" I ofcourse can not. What I tried was this in my test:
when(repository.updateWorkEntity(id: expected.id, executed: any)).thenAnswer((_) async => Right(expected));
to be able to make my mock return a object for my test, by using "any" in the place of the "DateTime.now()", but I get this error:
Invalid argument(s): The "any" argument matcher is used outside of
method stubbing (via when) or verification (via verify or
untilCalled). This is invalid, and results in bad behavior during
the next stubbing or verification.
So I guess I can not use any here, but then how do I get my mock to return an object when I do not control one of the input parameters?
Thank you
Søren
Use executed: anyNamed('executed') instead of executed: any

closure verification override default mocking

I have a method looks like this:
public void save(DbSession session,Wrappe wrapper,Wrappe wrappe){
//...other logic
//save wrapper
wrapper=(Wrapper)session.save(wrapper)
//set wrapper's id into wrappee
wrappee.setWrapperId(wrapper.getId());
//save wrappee
session.save(wrappee);
}
and test code looks like this:
given:
session.save(_) >> wrapperWithGeneratedId
when:
obj.save(session,wrapper,wrappee)
then:"wrapper got saved"
1*session.save(_) >> {Wrapper save ->
diffs(wrapper,saved)==null
}
and:"wrappee"
1*session.save(_) >> {Wrappe saved ->
diffs(wrappee,saved)==null
}
These test code will give an exception:
java.lang.ClassCastException: java.lang.Boolean cannot be cast to com.company.model.Wrapper
If commented verification closure in "then" section,test will pass,so I guess this section
1*session.save(_) >> {Wrapper save ->
diffs(wrapper,saved)==null
}
overrode this mocking:
session.save(_) >> wrapperWithGeneratedId
Is any way do both correctly?
1st. 'and' is syntactic sugar. It's just a way to visually separate code within the same block. Your last two mocks are effectively the same (although since you're testing behaviorally it will still verify that save is called twice.)
2nd. Assuming you want to verify thatdiffs(wrapper,saved)==null, that won't currently happen because it's not a 'base level' evaluation. Anything within then/where/closures/etc needs to be prepended with 'assert ' if you want to evaluate it.
3rd. A then block is scoped to its when block and can override existing mocks; your assumption that your mock was being overwritten is correct.
4th. Is there any reason you don't just include your return value alongside your evaluation?
2 * session.save(_) >> {Wrapper save ->
diffs(wrapper,saved)==null
return wrapperWithGeneratedId
}
5th. Your error is due to your mock returning a boolean (your assertion logic) which Groovy then tries (and fails) to parse into a Wrapper. My assumption for why this is happening is that .save() has a return type of Wrapper. To fix that you will either need to create a boolean constructor for Wrapper, or change your mock to return something Groovy can turn into a Wrapper (how-to in point 4)
Official Stub/Mock/Spy documentation (quite good, worth a read)

Breeze: Cannot read property 'xxx' of null?

I understand there are a few similar questions (e.g. here), but they all seem to be in different context. This is what I see in my chrome console:
Unhandled rejection reasons (should be empty):
["TypeError: Cannot read property 'compound' of null…://localhost:1476/Scripts/breeze.debug.js:234:15)", joinBy: function, equals: function, indexByKey: function, getByKey: function, sortOn: function]
I could see this error in my debugger at failed(error):
return manager.executeQuery(query).then(succeeded).fail(failed);
function failed(error) {
logger.logError(error);
}
For a specific object, it happens most of time, but no always (maybe one out of 10 is okay). The query from server returns without exception. As I figured, it seems to be related to the query with a specific include of table. However, in fact, in this case, the included table doesn't have any related entry yet (if there is an entry, it doesn't seem to have any problem). Any idea?
Okay, I accidentally found out what has caused this error. It is metadatastore post-construction initializer like
manager.metadataStore.registerEntityTypeCtor("Result", Result, initialize);
// constructor
function Result() {
}
// post-construction initializer
function initialize(result) {
result.cmpName = result.cs.compound.name;
}
where result.cs could be null sometimes.
Too bad the error message didn't provide any clue.

Executing my 3 calls one after the other in my activate function

I work on a project with durandal/breeze. I have the following code in my activate function:
var activate = function (routeData) {
initLookups();
var idTran = parseInt(routeData.idTran);
var idItin = parseInt(routeData.idItin);
if (idItin == -1)
idItin = datacontext.createItineraryDetailTransport(idTran);
datacontext.getTransportById(idTran, transport);
datacontext.getItineraryById(idItin, itinerary);
}
As you can see in the above code, I have 3 calls to the datacontext:
datacontext.createItineraryDetailTransport >> eventually... if (idItin == -1)
datacontext.getTransportById
datacontext.getItineraryById
The problem right now is that each call is not waiting for the previous one to complete before executing.
My question: how to proceed to be sure one call is finished before executing the next one? Please note that the first call is inside a condition... I'm thinking of using 'promises' but don't know.
Thanks.
The tricky part to what you're trying to do is conditionally chain three calls together.
You can simply chain multiple calls together using the then() method. However in your case, you need an initial promise to chain when the first condition isn't met.
The $.when() method is the trick here, because you can either chain an promise returned by Breeze, or you can chain a "dummy" promise, which is what $.when() gives you. If the first parameter passed to $.when is not a promise, then it returns a promise that is immediately resolved.
If I understand your question correctly, you should be able to write your code something like this:
var activate = function (routeData) {
initLookups();
var idTran = parseInt(routeData.idTran);
var idItin = parseInt(routeData.idItin);
var idtDeferred = $.when();
if (idItin == -1)
idtDeferred = datacontext.createItineraryDetailTransport(idTran);
idtDeferred
.then(datacontext.getTransportById(idTran, transport))
.then(datacontext.getItineraryById(idItin, itinerary));
}
Your code example looks like datacontext.createItineraryDetailTransport is supposed to set the idItin var, but I'm assuming that it returns a promise like typical breeze queries.
Certain parts of your example are unclear to me.
Is initLookups asynchronous? If so, do you have to wait for it to complete before performing the other asynchronous steps?
How can createItineraryDetailTransport be asynchronous when it returns the integer, idItin?
What the heck does createItineraryDetailTransport actually do? My guess is that idItin == -1 when you don't have an ItineraryDetailTransport entity yet and therefore don't have the key you need to call getItineraryById. If so, you have to restructure the signature of createItineraryDetailTransport.
Why does getItineraryById have to wait for getTransportById when they seemingly have nothing in common?
What are transport and itinerary? I'm guessing they are accidentally omitted variables that will be set with the results of the async calls within those datacontext methods.
Where is your error handling? What should happen if one of the async calls fails?
These issues must be sorted out before someone can give you a really good answer.
Joseph Gabriel seems to me to be mostly on the right track although I might have written it a little differently
...
var transport, itinerary;
var promise = (idItin == -1) ?
datacontext.createItineraryDetailTransport(aCallBackThatSets_idItin) :
Q.resolve(); // creates a resolved promise
promise = promise
.then(datacontext.getTransportById(idTran, transport)
.then(datacontext.getItineraryById(idItin, itinerary))
.fail(yourErrorHandler);
return promise; // don't forget to return the promise!
The most important step missing from Joseph Gabriel's suggestion ... and the reason you couldn't make his suggestion work ... is that it neglected to return the promise.
You must return a promise if you want Durandal to wait before activating the view.

Resources