How can one get the count of invocations on a mocked object?
At a particular point in a test I'd like to get the current count of invocations for a certain method, then continue the test and finally validate that the method was invoked one more time.
This would be something like:
[given([mockA interestingMethod]) willReturnInt:5];
<do some work that may call 'interestingMethod' one or two times>
NSInteger count = currentCountOfInvocations([mockA interestingMethod]); //or something similar
<do some more work that [hopefully] calls interesting method one more time>
[verifyCount(mockA, times(count + 1)) interestingMethod];
You can mock anything with a block. So let's use a block to increment our own counter.
__block NSUInteger interestingMethodCount = 0;
[given([mockA interestingMethod]) willDo:^id(NSInvocation *invocation) {
interestingMethodCount += 1;
return #5;
}];
<do some work that may call 'interestingMethod' one or two times>
NSUInteger countAtCheckpoint = interestingMethodCount;
<do some more work that [hopefully] calls 'interestingMethod' one more time>
assertThat(#(interestingMethodCount), is(equalTo(#(countAtCheckpoint + 1))));
Related
I am just starting with Spring Reactor and want to implement something that I would call 'standard pagination', don't know if there is technical term for this. Basically no matter what start and end date is passed to method, I want to return same amound of data, evenly distributed.
This will be used for some chart drawing in the future.
I figured out rough copy with algorithm that does exactly that, unfortunatelly before I can filter results I need to either count() or take last index() and block to get this number.
This block is surelly not the reactive way to do this, also it makes flux to call DB twice for data (or am I missing something?)
Is there any operator than can help me and get result from count() somehow down the stream for further usage, it would need to compute anyway before stream can be processed, but to get rid of calling DB two times?
I am using mongoDB reactive driver.
Flux<StandardEntity> results = Flux.from(
mongoCollectionManager.getCollection(channel)
.find( and(gte("lastUpdated", begin), lte("lastUpdated", end))))
.map(d -> new StandardEntity(d.getString("price"), d.getString("lastUpdated")));
Long lastIndex = results
.count()
.block();
final double standardPage = 10.0D;
final double step = lastIndex / standardPage;
final double[] counter = {0.0D};
return
results
.take(1)
.mergeWith(
results
.skip(1)
.filter(e -> {
if (lastIndex > standardPage)
if (counter[0] >= step) {
counter[0] = counter[0] - step + 1;
return true;
} else {
counter[0] = counter[0] + 1;
return false;
}
else
return true;
}));
So, I'm new to tweak development and obj c and I'm trying to change the style of dock with this code
%hook SBWallpaperEffect
-(void)setStyle: (NSInteger)arg1{
arg1 = 5;
}
%end
But it doesn't work. What am I doing wrong?
OK, I think this is the typical kind of pointer problem many programmers face. You are passing a NSInteger to the function, and arg1 is a copy of the value that is passed in. In other words, no matter how you change arg1 inside the function, the original variable does not change.
To make things more clear, look at the following code snippet:
NSInteger myInteger = 0;
NSInteger arg1;
arg1 = myInteger;
arg1 = 5;
// myInteger is still 0!
Changing arg1 does not change the value of myInteger, and that's what you're doing in your function. The arg1 copies the value of the integer passed in, be set to 5, and then gets released at the end of the function.
Instead, try this:
-(void)setStyle:(NSInteger *)arg1{
arg1 = 5;
}
and then call the function like this:
NSInteger myInteger = 0;
[self setStyle:&myInteger];
//myInteger is now 5!
Now you will get the result you want.
If you don't want to deal with these messy pointer stuff, use the returning value of the function to pass the number like this:
-(NSInteger)getStyle:(NSInteger)arg1{
// do some calculation
arg1 += 5;
return arg1;
}
or something like this (with no parameters):
-(NSInteger)getStyle{
return 5;
}
and call it like:
myInteger = [self getStyle:myInteger];
// or
myInteger = [self getStyle];
Now myInteger will also be 5. Hope this helps :)
Ok so i figured out that im using NSInteger instead of long long. Like this:
(void)setStyle:(long long)arg1;
Also, i was using
SBWallpaperEffect
Instead of
SBWallpaperEffectView
And i should've set the value inside %orig
So, this is the right way to write it:
%hook SBWallpaperEffectView
- (void)setStyle:(long long)arg1{
arg1 = 5;
%orig(arg1);
return;
}
%end
Is it possible to access in a test how many times an object has received a certain message? My goal is to test that a class has received two class method calls the same number of times.
Logically, it seems like this count would be stored somewhere as code is executed.
This would look something like
allow(SomeClass).to receive(:method_1).at_least(1).times
allow(SomeClass).to receive(:method_2).at_least(1).times
# setup and code here
expect(method_1_received_times).to eq (method_2_received_times)
Not very pretty, but your could set up your own counters like this:
#method_1_received_count = 0
#method_2_received_count = 0
allow(SomeClass).to receive(:method_1) { #method_1_received_count += 1 }
allow(SomeClass).to receive(:method_2) { #method_2_received_count += 1 }
# setup and code here
expect(#method_1_received_count).to eq(#method_2_received_count)
In an interview I recently attented I was asked to predict the output of a code segment. Even if I got it right, I was not able to explain how got it.
This is the code segment.
int num =2;
int (^ myblock)(void)=^{
return num*5;
};
NSLog(#"my block call 1 %d",myblock());
num = 5;
NSLog(#"my block call 2 %d",myblock());
Can anybody explain why the answer is 10 both times.?
Thanks
The num variable gets copied within the block if not marked with __block. This means that the external scope num and the inner num are actually kept at different addresses in memory and changing one doesn't affect the other. To force the compiler to use the same address, mark the variable with __block
The variable outside the block can't be changed except add '__block' before it. So the num always equal 2.
__block int num =2;
Then you will get 10 and 25
Add __block keyword before declaration so you can access the variable inside the block.
__block int num =2;
int (^ myblock)(void)=^{
return num*5;
};
NSLog(#"my block call 1 %d",myblock());
num = 5;
NSLog(#"my block call 2 %d",myblock());
Try this...
As Ryan Hodson says in his tutorial on Objective-C Blocks:
Non-local variables are copied and stored with the block as const
variables, which means they are read-only. Trying to assign a new
value to the make variable from inside the block will throw a compiler
error.
num is defined as a non-local variable.
The fact that non-local variables are copied as constants means that a
block doesn’t just have access to non-local variables—it creates a
snapshot of them. Non-local variables are frozen at whatever value
they contain when the block is defined, and the block always uses that
value, even if the non-local variable changes later on in the program.
If you want to reflect new value of num in block declare num as block variable
__block int num =2; // *** Declared as block variable, value change will effect inside block ***
Lets understand it with your example only.
Non-local(Non block) variable*
int num =2;
int (^ myblock)(void)=^{
return num*5;
};
NSLog(#"my block call 1 %d",myblock());
num = 5;
NSLog(#"my block call 2 %d",myblock());
Result :
my block call 1 10
my block call 2 10
block variable*
__block int num =2;
int (^ myblock)(void)=^{
return num*5;
};
NSLog(#"my block call 1 %d",myblock());
num = 5;
NSLog(#"my block call 2 %d",myblock());
Result :
my block call 1 10
my block call 2 25
I've seen the answer about invoking a block that is stored in an array, but I can't get it to work with parameters.
I store the array an a part of an object, then when it's in a method, I want to invoke it, however, I need parameters.
Also, is there any limit to the parameters.
Lastly, I'd rather not use the extra storage to the variable, so invoking directly while in the array would be better.
__block int x = 123; // x lives in block storage
void (^printXAndY)(int) = ^(int y) {
x = x + y;
NSLog(#"X and Y: %d %d\n", x, y);
};
self.blocks = #[printXAndY];
printXAndY(10); // this works
void(^block)(void) = self.blocks[0];
block(); // this works
block(10); // this doesn't work
[self.blocks[0] invoke ];
The problem is this line:
void(^block)(void) = self.blocks[0];
You are declaring 'block' to take no parameters and return nothing. If you want the block to take a parameter, you need to declare it like this:
void(^block)(int) = self.blocks[0];
Note that block(); will no longer work. And when you declared the block incorrectly, that line was undefined behavior.