I wonder if there is a reason for \Drupal\core\Url not being a service. Or can Url be injected somehow?

In my case I was adding a Unit test for an OG code, that has Url::fromRoute (test, code). In the current unit test it seems I can not mock the results of the Url::fromRoute call.

Comments

amitaibu created an issue. See original summary.

cilefen’s picture

Component: routing system » base system
Category: Support request » Feature request

URL generation is a service. From core.services.yml:

  url_generator:
    class: Drupal\Core\Render\MetadataBubblingUrlGenerator
    arguments: ['@url_generator.non_bubbling', '@renderer']
    calls:
      - [setContext, ['@?router.request_context']]

UrlGeneratorInterface has ::getPathFromRoute.

#2491981: There are too many ways to generate URLs and links

amitaibu’s picture

Status: Active » Fixed

I missed that one. Great, thanks :)

dawehner’s picture

genereteFromRoute is the right method to use, as this is exactly what \Drupal\Core\Url is using.

dawehner’s picture

In my case I was adding a Unit test for an OG code, that has Url::fromRoute (test, code). In the current unit test it seems I can not mock the results of the Url::fromRoute call.

Well, IMHO you should not mock the constructor of a value object, which Url mostly is. Url::fromRoute conceptually is just another and more readable name for new Url().

amitaibu’s picture

Title: Url should be a service » How to unit test methods using Url::fromRoute
Status: Fixed » Active

> conceptually is just another and more readable name for new Url().

@dawehner, can you please clarify how would you do it than - how would I controll the return Value of the access check? Given the accessManager service is under $this->isRouted()

amitaibu’s picture

Also, seems that the url_generator is not equivalent, as it returns the generated URL (that is, a string) and not the Url object which I need to later execute $url->access()

dawehner’s picture

Also, seems that the url_generator is not equivalent, as it returns the generated URL (that is, a string) and not the Url object which I need to later execute $url->access()

Ah, well, I would actually not use $url->access() to be honest, but rather use the access manager directly.

For me its too much responsibility in one class.

amitaibu’s picture

Status: Active » Fixed

Ah, well, I would actually not use $url->access() to be honest, but rather use the access manager directly.

Yeah, I might have to do it, since I don't see an alternative that can be easily unit tested (as stated in #7 url_generator doesn't allow me to use ::access().

I'll close for now. I believe you folks have answered my questions, thanks!

dawehner’s picture

Yeah, I might have to do it, since I don't see an alternative that can be easily unit tested (as stated in #7 url_generator doesn't allow me to use ::access().

Why do you not use, $this->accessManager->checkNamedRoute($url->getRouteName(), $url->getRouteParameters())?

Here is a though. An AccessCheckedUrl which wraps a URL with an access check when its printed out.

amitaibu’s picture

Why do you not use $this->accessManager->checkNamedRoute($url->getRouteName(), $url->getRouteParameters())?

I do, and it worked perfectly. It fitted my needs. Not sure about the use case of AccessCheckedUrl - I think that when you reach the point you print something, you should already know if they passes access check or not (e.g. so you could show a different message if non printed out)

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.