Custom ACTION as fixture member - google test - c++

I want to execute an action every time a mock function is called. I tried implementing this using ACTION_P. See the code below:
ACTION_P(CompleteRegistrationWithStatus, status)
{
arg1->registrationCompleted(status);
}
And the expectation goes like:
EXPECT_CALL(*mockObj, register(_)).WillOnce(CompleteRegistrationWithStatus(success));
Problem is, I had to use the same expectation multiple times, just different status. So I needed to put the expectation inside a member function of the test fixture to avoid code redundancy. But the function cannot access the ACTION_P I defined since it is not a member of the fixture.
I tried searching for ACTIONs that are fixture members, like that of MATCHERs, but to no avail.
Any suggestions for a possible solution or alternative? Any form of help is much appreciated. TIA!

I'm not sure that I understand the need to put the expectation in a member function of the fixture, but you should be able to get the behavior you want using InSequence:
{
InSequence s;
EXPECT_CALL(*mockObj, register(_))
.WillOnce(CompleteRegistrationWithStatus(success));
EXPECT_CALL(*mockObj, register(_))
.WillOnce(CompleteRegistrationWithStatus(failure));
}

Related

Is there a way to pass in complex arguments into Mocked Dart Services using Mockito?

I was looking at the documentation at: https://pub.dartlang.org/packages/mockito and was trying to understand it more. It seems that in the examples, the function stubs were accepting strings, but was kind of confused as to how I was going to implement my Mocked Services.
I was curious how I would do it. The services I have is pretty simple and straight forward.
class Group{}
class GroupService {}
class MockGroupService extends Mock implements GroupService {}
final mockProviders = [new Provider(MockGroupService, useExisting: GroupService];
So you can see I am using Angular dart.
I was creating a sample group in my Test file.
group("service tests", (){
MockGroupService _mock;
testBed.addProviders([mockProviders]);
setUp(() async {
fixture = await testBed.create();
_mock = new MockGroupService();
//This is where I was going to create some stubbs for the methods
when(_mock.add()).thenReturn((){
return null; //return the object.
});
//create additional when statements for edit, delete, etc.
});
});
So what i was thinking is that there would be an argument passed into add (or 2).... how would I properly code that in the when statement, and how do those 2 arguments reflect in the then statement?
Essentially, I was wanting to do a test with a complex class.. and pass it into add. Then it would just process it accordingly and return it.
Do i pass into the arguments something akin to: (using pseudocode)
when(_mock.add(argThat(hasType(Group)))).thenReturn((Group arg)=> arg);
or something similar? hasType isnt function, so im not 100% sure how to approach this design. Ideally, Im trying create the Group in the test, and then pass it into the add function accordingly. It just seems that the examples were showing Strings.
Yes mockito allows objects to be passed you can see examples in the test.
It is a bit hard to follow but you can see here that it uses deep equality to check if arguments are equal if no matchers are specified.
The second part of your question is a bit more complex. If you want to use the values that were passed into your mock as part of your response then you need to use thenAnswer. It provides you with an Invocation of what was just called. From that object you can get and return any arguments that were used in the method call.
So for your add example if you know what is being passing in and have complete access to it I would write:
Group a = new Group();
when(_mock.add(a)).thenReturn(a);
If the Group object is being created by something else I would write:
when(_mock.add(argThat(new isInstanceOf<Group>()))
.thenAnswer((invocation)=>invocation.positionalArguments[0]);
Or if you don't really care about checking for the type. Depending on what checks you are using for your test the type might already be checked for you.
when(_mock.add(any)).thenAnswer(
(invocation)=>invocation.positionalArguments[0]);
Or if you are using Dart 2.0:
when(_mock.add(typed(any))).thenAnswer(
(invocation)=>invocation.positionalArguments[0]);

Tweaking an output before testing using MRUnit

I am using creating an application using mapreduce2 and testing the same using MRUnit 1.1.0. In one of the tests, I am checking the output of a reducer which puts the 'current system time' in it's output. I.e. at the time the reducer executes, the timestamp is used in context.write() to be written along with the rest of the output. Now even though I use the same method to find the system time in the test method as the one I use in the reducer, the times calculated in both are generally a second apart, like 2016-05-31 19:10:02 and 2016-05-31 19:10:01. So the output in the two turns out to be different, example:
test_fe01,2016-05-31 19:10:01
test_fe01,2016-05-31 19:10:02
This causes an assertion error. I wish to ignore this difference in timestamps, so the tests pass if the rest of the output apart from the timestamp is matched. I am looking for a way to mock the method used for returning the system time, so that a hardcoded value is returned, and the reducer and the test both use this mocked method during the test. Is this possible to do? Any help will be appreciated.
Best Regards
EDIT: I have already tried Mockito's spy functionality in the my test:
MClass mc = Mockito.spy(new MClass());
Mockito.when(mc.getSysTime()).thenReturn("FakeTimestamp");
However, this gives a runtime error:
org.mockito.exceptions.misusing.MissingMethodInvocationException:
when() requires an argument which has to be 'a method call on a mock'.
For example:
when(mock.getArticles()).thenReturn(articles);
Also, this error might show up because:
1. you stub either of: final/private/equals()/hashCode() methods.
Those methods *cannot* be stubbed/verified.
2. inside when() you don't call method on mock but on some other object.
3. the parent of the mocked class is not public.
It is a limitation of the mock engine.
The method getSysTime() is public and static and class MClass is public and doesn't have any parent classes.
Assuming i understand your question, you could pass a time into the Reduce using the configuration object. In your reduce you could check if this configuration is set and use it, otherwise you use the system time.
This way you can pass in a known value for testing and assert you get that same value back.

Writing Unit Tests with ODataQueryOptions

I am new to writing test cases for WebAPI's. I have seen similar questions asked in the past, but not answered, but I am wondering how I would test my APIs if they have an ODataQueryOptions as part of the parameters. See below:
public IQueryable<Item> GetByIdAndLocale(ODataQueryOptions opts,
Guid actionuniqueid,
string actionsecondaryid)
Would I have to moq this? If so, how would this look? Any help would be appreciated.
For ODataQueryOptions perspective, you may want to test that all the OData query options can work with your Function. So firstly you need to create an instance of ODataQueryOptions. Here is an example:
HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, requestUri);
ODataQueryContext context = new ODataQueryContext(EdmCoreModel.Instance, elementType);
ODataQueryOptions options = new ODataQueryOptions(context, request);
So you need to create your own EDM model to replace EdmCoreModel.Instance, and replace requestUri with your query. elemntType in ODataQueryContext is "The CLR type of the element of the collection being queried".
I cannot tell from the phrasing, but is the above call (GetByIdAndLocale) the Web API that you are trying to test or are you trying to test something that is calling it?
One uses a mock or a stub to replace dependencies in a Unit Under Test (UUT). If you are testing GetByIdAndLocale() then you would not mock it though if it calls something else that takes the ODataQueryOptions as a parameter, you could use Moq to stub/mock that call.
If you are testing some unit that calls GetByIdAndLocale() then, yes, you could moq it. How exactly you might do this depends upon the goal (checking that the correct values are being passed in vs. checking that the returned IQueryable is correctly processed) basically, matching against It.IsAny() or against some matcher.
Which do you want to test?
GetByIdAndLocale(), something that calls it or something (not shown) that it calls?
What are you interested in verifying?
Correct options are passed in or the processing of the return from the mocked call?

Private method Unit testing with Jasmine

I was coding test cases for an angular application using jasmine. But many internal methods are declared as private in the services.
Example:
App.service('productDisplay', function(){
var myPrivate = function(){
//do sth
}
this.doOfferCal = function(product, date){
//call myPrivate
//do sth too
return offer;
}
});
Using jasmine it straightforward to code test for "doOfferCal" but I want to write unit test for myPrivate too.
How can I do it?
Thanks in advance.
Thanks jabko87.
In addition, if you want to pass the the arguments use the below example:
const myPrivateSpy = spyOn<any>(service, 'transformNative').and.callThrough();
myPrivateSpy.call(service, {name: 'PR'});
Note: Here service is the Class, transformNative is the private method and {name: 'PR'} passing an object argument
Is there a specific reason you wish to test your private methods?
By testing doOfferCal(), you're implicitly testing that myPrivate() is doing the right thing.
Though this is for RailsConf, Sandi Metz has a very good talk on what should be tested.
Achan is 100% right, but if you really need to call private method in your tests (what should be never :-) ) you can do it by:
var myPrivateSpy = spyOn(productDisplayService, "myPrivate").and.callThrough();
myPrivateSpy.call();
If you want to call your private method you just have to do it like this:
component["thePrivateMethodName"](parameters);
Where component is your service class or component class.
To test inner functions I call the outer function that calls the inner function and then vary my input according to what the inner function requires. So, in your case you would call productDisplay and vary your input based upon what myPrivate needs and then verify that you have the expected output. You could also spy on myPrivate and test things that way using .havebeencalledwith or .andcallthrough.

How to dynamically call a method from a different component by using cfscript?

I'm looking for the best way to dynamically call a method from a different component in cfscript. Notice that it's concerning a method in a different component. So far I've tried 3 different methods, but none of them seem be exactly what I'm looking for:
All cases are written in cfscript inside a component method. Let's say I'm trying to dynamically call the setName(required string name) method in the MyComponent component. All cases have following variables defined:
var myComp = new MyComponent();
var myMethod = "setName";
var args = {"name"="foo"};
use evaluate() for the job
evaluate("myComp.#myMethod#(argumentCollection=args)");
pros: is done with very little code
cons: code is not very 'clean' and use of evaluate() seems to have an 'evil' reputation in the online community. I wouldn't want my code to be evil.
use a cfml wrapper for <cfinvoke>
invoke("MyComponent", myMethod, args);
pros: I can use all functionality of cfinvoke
cons: It creates a new instance of MyComponent with every invoke.
create a dynamicMethod method in MyComponent
myComp.dynamicMethod(myMethod, args);
dynamicMethod of MyComponent:
public any function dynamicMethod(required string methodName, required struct argumentColl){
var cfcMethod = variables[arguments.methodName];
return cfcMethod(argumentCollection=arguments.argumentColl);
}
pros: I can finally call myComp directly. Most comfortable solution so far.
cons: I can now call private methods of MyComponent via dynamicMethod.
(I've also tried the 'function as variable' solution outside of MyComponent, but then the function looses its working context. e.g. if MyComponent would extend a component, the 'super' scope would no longer refer to the extended component).
None of these solutions seem to be perfect, so is there no other way to call a dynamic function from a different controller?
And if there isn't, which one of these is the best solution?
Any advice is welcome, thanks.
Good analysis.
One thing you could do here is to more-closely emulate <cfinvoke> with your wrapper function. <cfinvoke> will take either a component path or a component instance (ie: an object) in that COMPONENT attribute. So your 'con' of 'It creates a new instance of MyComponent with every invoke.' isn't really valid.
ColdFusion 10, btw, adds a invoke() function to achieve just this. I note you're on CF9, so this is no help to you. But it's perhaps relevant for other people who might land on this question.