-
-
Save nathanwoulfe/84f94e6ac890c4c57c7594214a700a4c to your computer and use it in GitHub Desktop.
private readonly IUmbracoContextFactory _context; | |
private readonly string _pluginPath; | |
public LicensingService(ILogger logger, IUmbracoContextFactory context) : base(logger) | |
{ | |
_context = context ?? throw new ArgumentNullException(nameof(context)); | |
_pluginPath = $"{IOHelper.ResolveUrl(SystemDirectories.AppPlugins).TrimEnd('/')}/plumber/"; | |
} | |
public Tuple<string, string> GetLicenseAndKey() { | |
using (var cref = _context.EnsureUmbracoContext()) | |
{ | |
// under test, with a mocked _context, HttpContext and Server are null (which is expected). I don't really want to mock all the way down, | |
// because the context factory is a pretty large, complex object | |
var keyPath = cref.UmbracoContext.HttpContext.Server.MapPath($"{_pluginPath}plumber.key"); | |
// instead, I think this would work fine, and remove the need for the factory entirely | |
// HttpContextManager is mine, and can be mocked | |
var licPath = HttpContextManager.Current.Server.MapPath($"{_pluginPath}plumber.lic"); | |
// other stuff happens here which is irrelevant to the mocking issue... | |
} | |
} |
Just need to mock MapPath, which is straightforward on the HttpContextManager object as it's pretty slim compared to UmbracoContextFactory. I think I can swap out one for the other with no issues (can't see any reason I wouldn't have context, or why I ever needed the factory in the firsts place)
That said, I think there are a couple of other places in the codebase where I do need the factory, so any advice around how to efficiently mock it, would be awesome
Yeah I agree, in most cases where I need to access a physical file I usually have some sort of IFileHelper that accesses Server MapPath behind the scenes and I can just mock the interface in my tests. Like you are doing with your HttpContextManager. So probably go with that with both the .key and .lic file.
Agree, still good to figure out how to mock the factory properly and I'll be glad to help out.
Great then I wont focus on the MapPAth but instead I will try to see if it's possible to just mock the UmbracoContext and HttpContext returned from EnsureUmbracoContext().
To be continued...
I Nathan.
I just looked at this and I would say you cant mock this.
The .EnsureUmbracoContext returns a concrete type UmbracoContextReference which has an internal constructor.
Would have liked to see some sort of Interface like IUmbracoContextReference being returned but sadly its not. :(
You could create your own abstraction layer on top of the UmbracoContextFactory, kind of like you've done with the HttpContextManager.
I also started experimenting with Reflections to get a test running but it seems a bit dirty and the test wont really match the reality so whats the point really? Probably just best to create a PR to Umbraco to make .EnsureUmbracoContext() testable.
Thanks Dennis, really appreciate your time. Might have to start nagging HQ to do make more ctors public
Hi. Are you looking to test if the .key file actually exists in that location (integration testing) or mocking the MapPath?