Hi,
The first question: How is the kong cache initialized? I’m asking, because I’ve just written unit tests that touch code where the cache is used, but I received a following error:
attempt to index field 'cache' (a nil value)
caused by calling a function singletons.cache:get(...)
in the following code:
-- #################
-- kong_cache.lua
-- #################
local singletons = require("kong.singletons")
local function run_cache(key, options, fetch_data_function, ...)
-- ...
local cached_value, error = singletons.cache:get(key, kong_cache_options, fetch_data_function, ...)
-- ...
end
I’m starting a kong instance, using helpers
, in busted tests, but it seems the Kong cache is still unavailable. I’ve looked at tests in a Kong’s repo. As I assume, tests init the cache by means of sending a request to somewhere. Could you confirm that?
The second question: Is there any solution to test a module, which uses the Kong cache, directly by means of calling functions of module (without sending a request to some endpoint)? For example, I’d like to test functions of builder.lua without sending a request in busted tests:
-- ##############
-- builder.lua
-- ##############
-- kong_cache is a wrapper on kong.singletons.cache
local kong_cache = require("kong.custom_modules.kong_cache")
function _M:run()
-- This statement uses the kong_cache variable.
end
-- other functions
1 Like
I am having this same question in developing a unit test for a plugin that uses the Kong cache. @Robert.pm, were you ever able to figure this out?
Or does anyone have any information on how to access the cache in a unit test of a custom plugin?
Hi @Tim_Kelley
You shouldn’t directly access Kong’s cache in tests unless you are testing the cache system. I suggest you take a look at how this is tested in existing plugins, in the key-auth plugin for instance (spec/03-plugins/09-key-auth/03-invalidations_spec.lua
).
Thanks for the reply @vinicius.mignot! I understand what that is doing, though it isn’t quite what I want to accomplish.
Here is my scenario. I have a plugin that is retrieving data from a URL (defined in plugin config). The response data is then cached and used for individual requests.
What I am wanting to do in the unit test is have a way to “mock” or pre-load the cache with data set in the unit test. I have attempted to go the route of mocking my module using the “package.loaded[“module”]” method as well as using the mockers.setup function from the Kong test helpers. Neither of those worked, so I was going down the route of just trying to pre-populate the cache, such that when the code is executed, it will be retrieved without making an HTTP call. I was struggling with that when I came upon this thread.
Another option I have considered is setting up a mock route in my unit test that would be used as the URL defined in the config that would then return mock data to use.
Just to add, I am running my tests using the kong-pongo utility.
If you happen to know what the best option for accomplishing this might be, any help would be appreciated! Thanks!
I usually prefer to emulate the actual behavior when creating tests, that way you know how your code will behave in the wild. So, if you are testing the caching of a request and then using the result of said cache, I would go the way of sending a request that would be cached, do not take into account the result of the first request (maybe just check if it returned 200
) and then send the requests that I actually wanted to check the behavior.
There’s a mocked HTTPS server in the fixtures, but if you want to cache response results, that might not be enough. Probably launching a really simple instance of Nginx, returning a known body using content_by_lua_block
is what you need.