I am creating a general general mock-client for testing HTTP-interactions. For this, I would like to be able to make a number of responses of the same method.
With a normal mock, this would not be a problem:
when(mock.execute(any(), any(), any())).thenReturn(firstResponse, otherResponses)
However, I am using a partial mock, where I simply want to mock method making the HTTP request, since there might not be access to a live end-point or the Internet in general for that matter in the context where the unit-tests are executed.
So I will be doing something like:
doReturn(response).when(spy).execute(hostCaptor.capture(), requestCaptor.capture(), contextCaptor.capture());
However, I would like to be able to support more than one response (not much of an "interaction"). But there are no doReturn-method, which takes a more than a single response at a time.
My first attempt on a solution was to do it iteratively:
Stubber stubber = null;
for (HttpResponse response : responses) {
if (stubber == null) {
stubber = doReturn(response);
} else {
stubber = stubber.doReturn(response);
}
}
stubber.when(spy).execute(hostCaptor.capture(), requestCaptor.capture(), contextCaptor.capture());
This does however fail to verify ("Unfinished stubbing detected") when running the test.
So - is there a way to achieve this with Mockito?
Thanks for reading.
You can write
doReturn( 1 ).doReturn( 2 ).doReturn( 3 ).when( myMock ).myMethod( any(), any(), any());
Edit:
If the values you want are in the array myArray, then you could also use
import static java.util.Arrays.asList;
import static org.mockito.Mockito.doAnswer;
import org.mockito.stubbing.answers.ReturnElementsOf
....
doAnswer( new ReturnsElementsOf( asList( myArray )))
.when( myMock ).myMethod( any(), any(), any());
The solution I found, was to use doAnswer to return the next response in the array.
Answer<HttpResponse> answer = new Answer<HttpResponse>() {
HttpResponse[] answers = responses;
int number = 0;
#Override
public HttpResponse answer(InvocationOnMock invocation) throws Throwable {
HttpResponse result = null;
if (number <= answers.length) {
result = answers[number];
number++;
} else {
throw new IllegalStateException("No more answers");
}
return result;
}
};
doAnswer(answer).when(spy).execute(hostCaptor.capture(), requestCaptor.capture(), contextCaptor.capture());
Related
In Retrofit 2, service methods representing http methods must return Call.
Call is a generic which must take the type representing the return object of the http method.
For example,
#GET("/members/{id}")
Call<Member> getMember(#Path("id") Long id);
For http methods such as delete, no content is returned. In cases like this, what parameter should be provided to Call?
Just set Void as the Type.
#DELETE("/members/{id}")
Call<Void> removeMember(#Path("id") Long id);
If you are using Kotlin/Retrofit/Rxjava/RxKotlin
#Headers(JwtKeyTokenWithValue)
#DELETE("/members/{id}")
fun removeMember(#Path("id") Long id): Completable
And can be subscribed this way
apiManager
.removeMember()
.subscribe(
{ Timber.i { "Member Removed!" } },
{ t -> Timber.e(t)})
If one pass a method as a funarg, how one can tell if passed function is a method, and get `this' object of a method is?
class A {
public function f():Void{
trace("f");
}
}
class B {
static function withFunarg(f:Void->Void):Void{
//HERE
}
public static function main(){
var a = new A();
withFunarg(a.f);
}
}
You cannot and there is no way to retrieve this. But it seems to me like an anti-pattern trying to do that. If you want the method and the container you can define a typedef:
typedef F = {
f : Void -> Void
}
Now you have the method and the container.
Haxe doesn't offer a cross-platform way to do that and it is generally not recomended.
But if you ultimately need this feature, you can use some platform-specific ways.
For example on js the following will work(at least on current haxe dev version):
static function getThis(f:Dynamic):Dynamic{
return (f.scope && f.method) ? f.scope : null;
}
It will return the object if the function is a method and a null otherwise. Result on calling on non-function is unspecified.
If you want to get the implicit `this' argument of a method, you have to make it explicit, like this
static function withMethodFunarg(o:{}, f:{}->Void):Void{
//HERE you have both object and function on this object
trace(o);
f(o);
}
public static function main(){
var a = new A();
withMethodFunarg(a,function(a){a.f()});
}
Which is, actually, pretty straight-forward: function is a function, no implicits, method caller is a method caller.
I want to create a wrapper that traps a particular exception and retries for all methods in a large (100+ methods) interface. I have the retry code working no worries, but I can't figure out how to hook up an implementation of the interface without cut'n'paste into all the methods.
I tried to use a missing method handler but that meant that I couldn't have it implement the interface. Abstract is obviously out as I won't be able to instantiate it.
I'm hoping for a better solution than creating the class as a template on the fly but I'm willing to do that.
Have you tried overriding invokeMethod for the interface?
YourInterface.metaClass.invokeMethod = {String name, args ->
def result
println "Calling method $name"
try{
result = metaClass.getMetaMethod(name, args).invoke(delegate, args)
}catch(YourException | AnyOtherException | Exception e){
println "Handling exception for method $name"
result = //Call retry code here
}
println "Called method $name"
result
}
Overriding invokeMethod works as as interceptor for all the method calls in the interface. Handle the exception for each method and return the success result.
I tried to use #dmahapatro's example but I kept getting IllegalArgumentException. I eventually realised that it only happened for mixin methods (the method shows the signature of the mixin). Instead of invoke() I needed to use doMethodInvoke() to get the appropriate type coersion.
errorProneInstance.metaClass.invokeMethod = { String name, args ->
def result
def method = delegate.metaClass.getMetaMethod(name, args)
while(true) {
try {
result = method.doMethodInvoke(delegate, args)
break
} catch (AnnoyingIntermittentButRetryableException e) {
print "ignoring exception"
}
}
result
}
I'm new to using a Mocking framework to mock objects for unit testing. I'm currently using Rhino Mocks and I would think it would have a method to do what I'm not finding it. Here is a LinqPad program (just copy and paste it in a C# program query and it will just work) that shows what I'm trying to do:
public interface MyTest{
int A(int i);
string B(int i);
}
/// This is an actual class that is a black box to me.
public class ActualClass : MyTest {
public int A(int i){
// Does some work
return ++i;
}
public string B(int i){
return A(i).ToString();
}
}
/// I'd like to create a mocked class that uses an instance of the actual class
/// to provide all of the implementations for the interface except for a single method
/// where I can check the parameter values, and provide my own return value,
/// or just call the actual class
public class MockedClass : MyTest {
private ActualClass _actual;
public MockedClass(ActualClass actual){
_actual = actual;
}
public int A(int i){
if(i == 1){
return 10;
}else{
return _actual.A(i);
}
}
public string B(int i){
return _actual.B(i);
}
}
void Main()
{
var mock = new MockedClass(new ActualClass());
mock.A(0).Dump();
mock.A(1).Dump();
mock.A(2).Dump();
mock.B(0).Dump();
mock.B(1).Dump();
mock.B(2).Dump();
}
Results:
1
10
3
1
2
3
What do I do to mock this out for unit testing. Do I need some sort of Dependency Injector?
Yes, you can change the return value of a mocked object based on the parameters passed in. I wouldn't take the approach of mixing a real dependency and a mocked dependency -- too much opportunity for a bug in the real dependency to creep in to your testing.
Here's an example you could use on your MyTest interface that examines the input argument of the mocked method and sets a return value accordingly:
var mock = MockRepository.GenerateStub<MyTest>();
mock.Stub(m => m.A(Arg<int>.Is.Anything))
.Return(99)
.WhenCalled(mi =>
{
var arg = Convert.ToInt32(mi.Arguments[0]);
switch (arg)
{
case 0:
mi.ReturnValue = 10;
break;
case 1:
mi.ReturnValue = 20;
break;
case 2:
mi.ReturnValue = 30;
break;
default:
mi.ReturnValue = -1;
break;
}
});
Note that the "Return(99)" is needed because when you stub a method that returns a value, Rhino.Mocks requires that you either define an exception to be thrown or define a return value. Even though we don't use the return value (since we provide our own inside the WhenCalled handler), it still must be defined or Rhino.Mocks will thrown an exception the first time the stub is called.
I ran into a problem today when trying to set a field using FieldInfo.SetValue() passing a DynamicObject as the second argument. In my case, the field is a Guid and the DynamicObject should be able to convert itself to a one (using TryConvert) but it fails with an ArgumentException.
Some code that shows the problem:
// Simple impl of a DynamicObject to prove point
public class MyDynamicObj : DynamicObject
{
public override bool TryConvert(ConvertBinder binder, out object result)
{
result = null;
// Support converting this to a Guid
if (binder.Type == typeof(Guid))
{
result = Guid.NewGuid();
return true;
}
return false;
}
}
public class Test
{
public Guid MyField;
}
class Program
{
static void Main(string[] args)
{
dynamic myObj = new MyDynamicObj();
// This conversion works just fine
Guid guid = myObj;
var test = new Test();
var testField = typeof(Test).GetField("MyField");
// This, however, fails with:
// System.ArgumentException
// Object of type 'ConsoleApplication1.MyDynamicObj' cannot be converted to type 'System.Guid'.
testField.SetValue(test, myObj);
}
}
I'm not very familiar with the whole dynamicness of C# 4, but this felt to me like something that should work.. What am I doing wrong? Is there another way of doing this?
No, this shouldn't work - because the dynamic portion ends where your code ends. The compiler is calling a method with a signature of
void SetValue(Object obj, Object value)
That method call is dynamic, but it's just going to end up passing in a reference to the instance of MyDynamicObj. The call is resolved at execution time, but nothing in SetValue knows anything about the dynamic nature of the object whose reference you're passing in.
Basically you need to perform the dynamic part (the conversion in this case) in your code - the bit that involves the C# 4 compiler doing all its tricks. You've got to perform that conversion, and then you can call SetField.
To put it another way - it's a bit like calling SetField with a field of type XName, but passing in a string. Yes, there's a conversion from string to XName, but it's not SetField's job to work that out. That's the compiler's job.
Now, you can get this to work by making the compiler do some of the work, but you still need to do some with reflection:
static void Main(string[] args)
{
dynamic myObj = new MyDynamicObj();
var test = new Test();
var testField = typeof(Test).GetField("MyField");
var method = typeof(Program)
.GetMethod("Convert", BindingFlags.Static | BindingFlags.NonPublic);
method = method.MakeGenericMethod(testField.FieldType);
object converted = method.Invoke(null, new object[] {myObj});
testField.SetValue(test, converted);
}
static T Convert<T>(dynamic input)
{
return input;
}
You need an explicit cast to invoke the TryConvert:
testField.SetValue(test, (Guid)myObj);
Not sure if this is what you need though. Maybe there's some way to reflectively say ((DynamicObject)myObj).TryConvert(/*reflected destination type here*/, result)
Other attempts that failed, some of them require things like a certain interface be implemented, so they basically don't make use of TryConvert but maybe an alternative way to accomplish what you want:
Type secondType = testField.FieldType;
TypeConverter tc = TypeDescriptor.GetConverter(typeof(MyDynamicObj));
object secondObject = tc.ConvertTo(myObj,typeof( Guid));
//var secondObject = Convert.ChangeType(myObj, secondType);//Activator.CreateInstance(secondType);
//secondObject = myObj;
testField.SetValue(test, secondObject);