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.
Related
I am having problems to decorate the final class "DocumentGenerator" (in vendor/shopware/core/Checkout/Document/Service/DocumentGenerator.php) and overwrite the "generate" function inside of it.
I tried to decorate it the usual way, but an error is thrown because the "DocumentController" class excepts the original class and not my decorated one?
Argument 2 passed to Shopware\Core\Checkout\Document\DocumentGeneratorController::__construct() must be an instance of Shopware\Core\Checkout\Document\Service\DocumentGenerator
Its also not possible to extend from the class in my decorated class, because the "DocumentGenerator" is a final class.
My goal is to execute additional code, after an order document is generated. Previously I successfully used to decorate the "DocumentService" Class, but its marked as deprecated and shouldnt be used anymore. Also the "DocumentGenerator" class is used for the new "bulkedit" function for documents as of Version 6.4.14.0
I'm grateful for every tip.
As #j_elfering already wrote it's by design that you should not extend that class and therefore also shouldn't decorate it.
To offer a potential alternative:
Depending on what you want to do after a document has been generated it might be enough to add a subscriber to listen to document.written, check if it was a new document created and then work with the data from the payload for fetching/persisting data depending on that.
public static function getSubscribedEvents()
{
return [
'document.written' => 'onDocumentWritten',
];
}
public function onDocumentWritten(EntityWrittenEvent $event): void
{
foreach ($event->getWriteResults() as $result) {
if ($result->getOperation() !== EntityWriteResult::OPERATION_INSERT) {
// skip if the it's not a new document created
continue;
}
$payload = $result->getPayload();
// do something with the payload
}
}
Probably not what you want to hear but: The service is final in purpose as it is not intended to be decorated.
So the simple answer is you can't. Depending on your use case there may be other ways that don't rely on decoration.
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.
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
Using C# 4.0 features I want a generic wrapper for encapsulating functions and add a TimeOut parameter to them.
For example we have a function like:
T DoLengthyOperation()
Using Func we have:
Func<T>
This is good and call the function even Sync (Invloke) or Async(BeginInvoke).
Now think of a TimeOut to be added to this behavior and if DoLengthyOperation() returns in specified time we have true returned, otherwise false.
Something like:
FuncTimeOut<in T1, in T2, ..., out TResult, int timeOut, bool result>
Implement C# Generic Timeout
Don't return true/false for complete. Throw an exception.
I don't have time to implement it, but it should be possible and your basic signature would look like this:
T DoLengthyOperation<T>(int TimeoutInMilliseconds, Func<T> operation)
And you could call this method either by passing in the name of any Func<T> as an argument or define it place as a lambda expression. Unfortunately, you'll also need to provide an overload for different kind of function you want, as there's currently no way to specify a variable number a generic type arguments.
Instead of mixing out and bool I would instead construct a separate type to capture the return. For example
struct Result<T> {
private bool _isSuccess;
private T _value;
public bool IsSucces { get { return _success; } }
public T Value { get { return _value; } }
public Result(T value) {
_value = value;
_isSuccess = true;
}
}
This is definitely possible to write. The only problem is that in order to implement a timeout, it's necessary to do one of the following
Move the long running operation onto another thread.
Add cancellation support to the long running operation and signal cancellation from another thread.
Ingrain the notion of timeout into the operation itself and have it check for the time being expired at many points in the operation.
Which is best for you is hard to determine because we don't know enough about your scenario. My instinct though would be to go for #2 or #3. Having the primary code not have to switch threads is likely the least impactful change to your code.
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);
}
}