Returning mock objects with Mockito using given arguments - mockito

For my JUnit Tests with Mockito, I am doing the following:
Mockito.lenient().when(tokenService.create(String id, Any)).thenReturn(new String (id))
Mockito.lenient().when(voucherRepo.findById(id String).thenReturn(new Voucher(id));
I would like to access the String id given to tokenService.create() and voucherRepo.findById() methods, create and then return mock objects using it. How it can be done?

Mockito.when(voucherRepo.findById(id)).thenReturn(new Voucher(id));
Your solution should work and is probably the preferred solution for any clear defined test.
As you know in your test what the exact id is, you can just return the specific object for it.
Another way to do this - for arbitrary strings - is using mockito's thenAnswer funtionality:
Mockito.when(voucherRepo.findById(Mockito.any(String.class))).thenAnswer(new Answer<Voucher>() {
#Override
public Voucher answer(InvocationOnMock invocation) throws Throwable {
Object[] args = invocation.getArguments();
String id = (String) args[0];
return new Voucher(id);
}
});
I am not sure what reason you have to do that in your test (as this a rather arbitrary defintion), but in doubt consider adding some more context to your question.

Related

Acumatica - An object Reference is Required or the non-static field, method, or property

hi does anyone encountered this error? everytime I use PXSelect on a foreach loop in which on the other source code does but on my code does not, could anyone identify the cause? the code below is also the the original source code from Acumatica but I only changed the Datamember from PaymentCharges to OtherCharges
[PXOverride]
public void VoidCheckProc(ARPayment doc)
{
foreach (PXResult<ARPaymentChargeTran> paycharge in PXSelect<ARPaymentChargeTran, Where<ARPaymentChargeTran.docType, Equal<Required<ARPayment.docType>>, And<ARPaymentChargeTran.refNbr, Equal<Required<ARPayment.refNbr>>>>>.
Select(this, doc.DocType, doc.RefNbr))
{
ARPaymentChargeTran charge = PXCache<ARPaymentChargeTran>.CreateCopy((ARPaymentChargeTran)paycharge);
charge.DocType = Document.Current.DocType;
charge.CuryTranAmt = -1 * charge.CuryTranAmt;
charge.Released = false;
charge.CuryInfoID = Document.Current.CuryInfoID;
charge.CashTranID = null;
//PaymentCharges.Insert(charge);
OtherCharges.Insert(charge);
}
}
I believe, you are writing this method in an extension for the base BLC
So instead of using 'this', use 'this.Base'
The Select method is non-static, as the error message says, but you call it on the PXSelect<...>-type. You need to have an instance of that type.
Based on Hybridzz answer, I assume you used the wrong overload of the Select-method. Probably your arguments do not have the correct type, so the compiler selects the best fitting overload of the method. In this case, it selects the one accepting only the argument params object[] o, which is non-static. A bit misleasing design of the API you use.

The test failure message for mockito verify

For a parameter class
class Criteria {
private Map params;
public getMap(){ return params; }
}
and a service method accept this criteria
class Service{
public List<Person> query(Criteria criteria){ ... }
}
A custom featureMatcher is used to match the criteria key
private Matcher<Criteria> hasCriteria(final String key, final Matcher<?> valueMatcher){
return new FeatureMatcher<Criteria, Object>((Matcher<? super Object>)valueMatcher, key, key){
#Override protected Object featureValueOf(Criteria actual){
return actual.getMap().get(key);
}
}
}
when using mockito to veryify the arguments:
verify(Service).query((Criteria) argThat("id", hasCriteria("id", equalTo(new Long(12)))));
The error message shows that:
Argument(s) are different! Wanted:
Service.query(
id <12L>
);
-> at app.TestTarget.test_id (TestTarget.java:134)
Actual invocation has different arguments:
Service.query(
app.Criteria#509f5011
);
If I use ArugmentCaptor,
ArgumentCaptor<Criteria> argument = ArgumentCaptor.forClass(Criteria.class);
verify(Service).query(argument.capture());
assertThat(argument.getValue(), hasCriteria("id", equalTo(new Long(12))));
The message is much better:
Expected: id <12L> but id was <2L>
How can I get such message, without using ArgumentCaptor?
The short answer is to adjust the Criteria code, if it's under your control, to write a better toString method. Otherwise, you may be better off using the ArgumentCaptor method.
Why is it hard to do without ArgumentCaptor? You know you're expecting one call, but Mockito was designed to handle it even if you have a dozen similar calls to evaluate. Even though you're using the same matcher implementation, with the same helpful describeMismatch implementation, assertThat inherently tries once to match where verify sees a mismatch and keeps trying to match any other call.
Consider this:
// in code:
dependency.call(true, false);
dependency.call(false, true);
dependency.call(false, false);
// in test:
verify(mockDependency).call(
argThat(is(equalTo(true))),
argThat(is(equalTo(true))));
Here, Mockito wouldn't know which of the calls was supposed to be call(true, true); any of the three might have been it. Instead, it only knows that there was a verification you were expecting that was never satisfied, and that one of three related calls might have been close. In your code with ArgumentCaptor, you can use your knowledge that there's only one call, and provide a more-sane error message; for Mockito, the best it can do is to output all the calls it DID receive, and without a helpful toString output for your Criteria, that's not very helpful at all.

Get parameter values from method at run time

I have the current method example:
public void MethodName(string param1,int param2)
{
object[] obj = new object[] { (object) param1, (object) param2 };
//Code to that uses this array to invoke dynamic methods
}
Is there a dynamic way (I am guessing using reflection) that will get the current executing method parameter values and place them in a object array? I have read that you can get parameter information using MethodBase and MethodInfo but those only have information about the parameter and not the value it self which is what I need.
So for example if I pass "test" and 1 as method parameters without coding for the specific parameters can I get a object array with two indexes { "test", 1 }?
I would really like to not have to use a third party API, but if it has source code for that API then I will accept that as an answer as long as its not a huge API and there is no simple way to do it without this API.
I am sure there must be a way, maybe using the stack, who knows. You guys are the experts and that is why I come here.
Thank you in advance, I can't wait to see how this is done.
EDIT
It may not be clear so here some extra information. This code example is just that, an example to show what I want. It would be to bloated and big to show the actual code where it is needed but the question is how to get the array without manually creating one. I need to some how get the values and place them in a array without coding the specific parameters.
Using reflection you can extract the parameters name and metadata but not the actual values :
class Program
{
static void Main(string[] args)
{
Program p = new Program();
p.testMethod("abcd", 1);
Console.ReadLine();
}
public void testMethod(string a, int b)
{
System.Diagnostics.StackTrace st = new System.Diagnostics.StackTrace();
StackFrame sf = st.GetFrame(0);
ParameterInfo[] pis = sf.GetMethod().GetParameters();
foreach (ParameterInfo pi in pis)
{
Console.Out.WriteLine(pi.Name);
}
}
}

AssertWasCalled on method in SystemUnderTest

I'm getting into TDD; using nUnit and RhinoMocks 3.5.
I'm trying to figure out how to AssertWasCalled on a method in the SystemUnderTest (SUT). My understanding is that you can't mock the system under test. In fact, my current test results in an exception because the I'm using the AssertWasCalled on the SUT.
OrdersPresenter:
public void OnViewLoad_GetOrders()
{
var orders = GetOrders();
View.Model.Orders = orders;
}
public List<Orders> GetOrders()
{
return _ordersRepository.GetAll();
}
OrdersPresenterTest:
_ordersPresenter = new OrdersPresenter(_view, _ordersRepository);
[Test]
public void OnViewLoad_GetOrders_Should_Call_GetOrders()
{
_view.Raise(v => v.LoadOrders += _ordersPresenter.OnViewLoad_GetOrders, view, new EventArgs);
_ordersPresenter.AssertWasCalled(d => d.GetOrders); // Getting non-mock exception here
}
How do I Assert GetOrders was called in the SUT? I haven't been able to figure it out in the docs.
Any help is greatly appreciated.
Edit:
I understand the GetOrders method in the SUT should be private. I went back thru Roy Osherove's Art of Unit Testing to see how to test private methods. Roy says making a method public (to test against) is not necessarily a bad thing, so I will keep it public.
So I've written a test for GetOrders and I assert the return value ShouldBe a list of orders. That said, I believe I need to restructure my test for OnViewLoad_GetOrders by stubbing the value I get from GetOrders and asserting the results of my actions on that object.
Can someone confirm and explain?
You can not use AssertWasCalled() on not-mocked objects. Just abstract class OrdersPresenter by an interface (use Extract Interface refactoring technique) and then
var ordersPresenter = MockRepository.GenerateMock<IOrderRepository>();
view.Raise(...);
_ordersPresenter.AssertWasCalled(d => d.GetOrders);
BTW,
for me it is not clear why RhinoMocks not used generic parameter constraint for AssertWasCalled
public static void AssertWasCalled<T>(this T mock, Action<T> action,
Action<IMethodOptions<object>> setupConstraints)
Basically T is not limited, but I believe it would be better limit it to somethign like IMockMarkerInterface

IEnumerable<T>.ConvertAll & DDD

I have an interesting need for an extension method on the IEumerable interface - the same thing as List.ConvertAll. This has been covered before here and I found one solution here. What I don't like about that solution is he builds a List to hold the converted objects and then returns it. I suspect LINQ wasn't available when he wrote his article, so my implementation is this:
public static class IEnumerableExtension
{
public static IEnumerable<TOutput> ConvertAll<T, TOutput>(this IEnumerable<T> collection, Func<T, TOutput> converter)
{
if (null == converter)
throw new ArgumentNullException("converter");
return from item in collection
select converter(item);
}
}
What I like better about this is I convert 'on the fly' without having to load the entire list of whatever TOutput's are. Note that I also changed the type of the delegate - from Converter to Func. The compilation is the same but I think it makes my intent clearer - I don't mean for this to be ONLY type conversion.
Which leads me to my question: In my repository layer I have a lot of queries that return lists of ID's - ID's of entities. I used to have several classes that 'converted' these ID's to entities in various ways. With this extension method I am able to boil all that down to code like this:
IEnumerable<Part> GetBlueParts()
{
IEnumerable<int> keys = GetBluePartKeys();
return keys.ConvertAll<Part>(PartRepository.Find);
}
where the 'converter' is really the repository's Find-by-ID method. In my case, the 'converter' is potentially doing quite a bit. Does anyone see any problems with this approach?
The main issue I see with this approach is it's completely unnecessary.
Your ConvertAll method is nothing different than Enumerable.Select<TSource,TResult>(IEnumerable<TSource>, Func<TSource,TResult>), which is a standard LINQ operator. There's no reason to write an extension method for something that already is in the framework.
You can just do:
IEnumerable<Part> GetBlueParts()
{
IEnumerable<int> keys = GetBluePartKeys();
return keys.Select<int,Part>(PartRepository.Find);
}
Note: your method would require <int,Part> as well to compile, unless PartRepository.Find only works on int, and only returns Part instances. If you want to avoid that, you can probably do:
IEnumerable<Part> GetBlueParts()
{
IEnumerable<int> keys = GetBluePartKeys();
return keys.Select(i => PartRepository.Find<Part>(i)); // I'm assuming that fits your "Find" syntax...
}
Why not utilize the yield keyword (and only convert each item as it is needed)?
public static class IEnumerableExtension
{
public static IEnumerable<TOutput> ConvertAll<T, TOutput>
(this IEnumerable<T> collection, Func<T, TOutput> converter)
{
if(null == converter)
throw new ArgumentNullException("converter");
foreach(T item in collection)
yield return converter(item);
}
}

Resources