Can I mock the `cgi` scope?
# testing
r
Can I mock the
cgi
scope?
a
kinda 🙂 I think your choices are: • hide the CGI scope in a function (which you can then mock what the function returns) • Pass the CGI scope into your object as a dependency when you create it so the CFC isn't hard coded to CGI scope (then in tests you pass in whatever you want) • you can trick Adobe CF to read a
variables.CGI
scoped variable before it looks for the actual CGI scope (due to the order ACF does scope hunting) so you can do
sut.$property("CGI", "variables", {});
r
Unfortunately I'm trying to add some test coverage to some existing code that reads
cgi.QUERY_STRING
so I can refactor the sh!t out of it. And that trick is ACF only, not Lucee?
a
Lucee has options on how strict you are searching scopes so I'd expect it to vary depending in setup I'm afraid.
r
Okay, I'll give that a try, thanks John.
a
I think I'd just move the
cgi.QUERY_STRING
into a new function in the component under test and then mock what that function returns.
Small change that will then allow you to retrofit test coverage before you go into refactor beast mode,
r
Yes, I wanted not to have to touch the exist code but I think I'll have to concede that principle to get pass this blocker.
A good idea though which I hadn't considered, so thanks again.
a
Just reading through this. I agree with what @aliaspooryorik sez. Pretty sure you can't monkey-with or write-to the CGI scope as it stands. So lesser of two evils is to extract just that one bit for your test. For greenfields work... it's always important to wrap these things in an adapter precisely for this reason. I realise this does not help you in this case @richard.herbert;-)
r
Yes, I had a vague memory, they're all like that nowadays it seems, that there was a way to write to
cgi
but that might have been at the web server level I'm remembering. I would say more "_don't depend on the CGI scope as it can vary between web servers_".
a
Only yer routing and/or yer controllers (maybe) should care about stuff in the CGI scope. Although I'd contend that a controller method should receive a
Request
object instance, which contains something like a
cgi
property which has data from the CGI scope in it. Even a controller method should "never" access the CGI scope. Nothing beyond the controller should be fussing with the sort of values that come from the CGI scope I reckon. Maybe some property value derived from something in the CGI scope, but not like
CGI.remote_addr
etc
a
I do reference CGI scope in error handling - just trying to grab everything I can to replicate production errors - so I think that's a valid case (of course I'm just logging it rather than using it for any logic)
j
Can I mock the
cgi
scope?
What did the cgi scope do to deserve mockery?
r
Be referenced directly in some sh!t code.
j
Ahh. Good point. Mock away.
r
An ajax component was reaching out to the
cgi.QUERY_STRING
to loop over and then pass onto another component...
Copy code
<cfloop index="pair" list="#cgiQueryString()#" delimiters="&">
	<cfset argument_name = listFirst(pair, "=")>
	<cfset argument_name = REReplace(urlDecode(argument_name),'<[^>]*>','','all')>
	<cfset argument_value = urlDecode(listLast(pair, "="))>

	<cfset "passInArgs.#argument_name#" = argument_value>
</cfloop>
I'm writing some tests before I refactor the bejeezus out of it!