PowerMock MockStatic expect not working for EasyMock anyObject - easymock

This seems ok
EasyMock.expect(URLDecoder.decode("test", "UTF-8")).andThrow(new UnsupportedEncodingException("This is a test"));
This doesn't
EasyMock.expect(URLDecoder.decode((String) EasyMock.anyObject(), "UTF-8")).andThrow(new UnsupportedEncodingException("This is a test"));
This throws the following
java.lang.IllegalStateException: 2 matchers expected, 1 recorded.
This exception usually occurs when matchers are mixed with raw values when recording a method:
foo(5, eq(6)); // wrong
You need to use no matcher at all or a matcher for every single param:
foo(eq(5), eq(6)); // right
foo(5, 6); // also right
at org.easymock.internal.ExpectedInvocation.createMissingMatchers(ExpectedInvocation.java:47)
at org.easymock.internal.ExpectedInvocation.<init>(ExpectedInvocation.java:40)
at org.easymock.internal.RecordState.invoke(RecordState.java:78)
at org.easymock.internal.MockInvocationHandler.invoke(MockInvocationHandler.java:40)
at

If you're going to use 1 matcher in your expectation, then you need to use all matchers.
Sadly, this isn't explained very well in the error message you get out of EasyMock, but adding an EasyMock.eq() arround the other string should do the trick.
EasyMock.expect(URLDecoder.decode((String) EasyMock.anyObject(), EasyMock.eq("UTF-8"))).andThrow(new UnsupportedEncodingException("This is a test"));

Related

EasyMock - expect anyObject except some

Let's say I have a method like this:
foo (A a, B b)
I want to set expectation so that anyObject is expected except some, like the imaginary code below:
expect(mockedObject).foo(anyObject(A.class), anyObject(B.class)).andReturn(something).anyTimes();
expect(mockedObject).foo(new A("1"), new B("1")).andReturn(something).times(0);
expect(mockedObject).foo(new A("2"), new B("2")).andReturn(something).times(0);
expect(mockedObject).foo(new A("3"), new B("3")).andReturn(something).times(0);
However there is no times(0) in EasyMock. I can create a chain of EasyMock.or() and EasyMock.not() but it's going to be dirty when there are a lot of unexpected objects.
On Mockito I can easily specify
verify(mockedObject, never()).foo(new A("1"), new B("1"));
What's the easiest way on EasyMock to do the same thing as above?
It is something missing indeed.
Right now, the easier is to capture() all your parameters and then check that no invalid permutation was used.

How to handle errors in custom MapFunction correctly?

I have implemented MapFunction for my Apache Flink flow. It is parsing incoming elements and convert them to other format but sometimes error can appear (i.e. incoming data is not valid).
I see two possible ways how to handle it:
Ignore invalid elements but seems like I can't ignore errors because for any incoming element I must provide outgoing element.
Split incoming elements to valid and invalid but seems like I should use other function for this.
So, I have two questions:
How to handle errors correctly in my MapFunction?
How to implement such transformation functions correctly?
You could use a FlatMapFunction instead of a MapFunction. This would allow you to only emit an element if it is valid. The following shows an example implementation:
input.flatMap(new FlatMapFunction<String, Long>() {
#Override
public void flatMap(String input, Collector<Long> collector) throws Exception {
try {
Long value = Long.parseLong(input);
collector.collect(value);
} catch (NumberFormatException e) {
// ignore invalid data
}
}
});
This is to build on #Till Rohrmann's idea above. Adding this as an answer instead of a comment for better formatting.
I think one way to implement "split + select" could be to use a ProcessFunction with a SideOutput. My graph would look something like this:
Source --> ValidateProcessFunction ---good data--> UDF--->SinkToOutput
\
\---bad data----->SinkToErrorChannel
Would this work? Is there a better way?

Extending Array in Typescript breaks constructor

while playing around with typescript I ran into then following interesting behavior:
class ExtArray<U> extends Array<U> {
constructor(...args : U[]) {
super(...args);
}
public contains(element : U) : boolean {
var i = this.indexOf(element);
return i !== -1;
}
}
var test : ExtArray<string> = new ExtArray("a", "b", "c");
test.push("y");
console.log(test.length); // 1
console.log(test[0]); // y
console.log(test[1]); // undefined
console.log("Has a: " + test.contains("a")); // Has a: false
console.log("Has y: " + test.contains("y")); // Has y : true
I've added the output of the console.log statements as comments.
See this typescript playground for an executable example and the javascript code.
As you can see it seems as if the elements passed to the constructor are not added to the array.
The section about extending expression in Whats new in Typescript suggests that it should be possible to extend the native Array type like that in typescript 1.6.
Also I didn't find anything in the typescript language reference,
that explains this behavior.
Most of the other questions about extending Arrays I found here are at least one year old and usually talk about a pre-1.0 version of typescript and therefore suggest to set up the prototype chain directly.
I seriously don't see what is going wrong here and I'm starting to suspect a typescript bug.
Or at least some kind of undocumented restriction for extending Arrays.
What goes wrong here?
It's a little easier to understand what's going on if you JSON.stringify() your object:
var test : ExtArray<string> = new ExtArray("a", "b", "c");
test.push("y");
// outputs {"0":"y","length":1}
document.writeln(JSON.stringify(test));
If you instead new-up a native Array, the resulting object is quite a bit different:
var test : Array<string> = new Array("a", "b", "c");
test.push("y");
// outputs ["a","b","c","y"]
document.writeln(JSON.stringify(test));
I agree with you that the documentation seems to imply that the subclass's constructor should behave the way you're expecting. Even stranger, I seem to get inconsistent results when testing whether or not the subclass is an Array using the methods described here:
test.constructor === Array // false
test instanceof Array // true
Array.isArray(test) // false
I would suggest opening an issue on the TypeScript GitHub repository. Even if this is the expected behavior, the official documentation is misleading and should clarify what exactly is expected when native objects are subclassed.

How to assert that every item in collection is within range

I have a Groovy array that will get a set number of random Integer Values. And I want to assert that each item in the array has a value within the given range. I'm trying to use Hamcrest Matchers. So my test looks like this:
#Test
void testShouldReturnArrayOfStats(){
def results = pg.rollStats()
assertThat results, everyItem(both(greaterThan(0)).and(lessThanOrEqualTo(6)))
}
When I run the test I get an assertionError
java.lang.AssertionError: Expected: every item is (a value greater than <0> and a value less than or equal to <6>)
but: was [<6>, <3>, <5>, <4>, <3>, <2>]
I've tried some variations of this but I'm not getting a passing test. just by looking at the "But:was" portion of the error I can seen that all 6 values meet the requirements, but the test still fails.
I've not used Groovy or Hamcrest for very long so I'm sure that I'm missing something.
Thanks
Could you just use groovy?
assert results.every { it in 1..6 }

Underscore isObject() sometimes not work

When I use nodeUnit to write unit tests for Backbone models, something weird happened, the question can be summarized as:
var Player = Backbone.Model.extend({});
var player = new Player({name: 'Jacky'});
Then I update the player name with: player.set('name', 'Scott').
But I found that the name attribute is not updated at all(No validate function for this model), and there are weird attributes like: [0]: n, [1]: a, [2]: m, [3]: e.
It works fine if I changed the update method to player.set({name: 'Scott'}).
I did some quick investigation and found that Backbone.Model.set method depends on Underscore.isObject() method, and the latter is implemented as:
_.isObject = function(obj) {
return obj === Object(obj);
};
I called the isObject() method in nodeUnit test cases, and in the first case it works fine, but in latter cases, it does not work as expected, for example isObject('name') will return true instead of the expected false.
Anyone have any idea what caused this?
Can you make sure that you are using the latest version of Backbone? Backbone in older versions didn't support shortcut version for the set method (.set(key, value)) and allowed only object with attribute/value pairs as a parameter.
(i believe it was added in 0.9)

Resources