Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Providing a sensitive API key to testthat

Tags:

r

testthat

I'm attempting to setup mocking of an API to increase the test coverage of an API package I maintain (https://github.com/condwanaland/scrobbler)

Installable with

remotes::install_github("condwanaland/scrobbler")

I've used httptest to record the results of hitting the API

library(httptest)

capture_requests({
  download_scrobbles(.limit1 = TRUE)
})

capture_requests stores the result of this request in json files. The mock then loads this file in place of making the actual request

In download_scrobbles(), the API username and key are loading via environment variables

Sys.getenv('LASTFM_API_USERNAME'); Sys.getenv('LASTFM_API_KEY')

However, I then have setup a snapshot test to check that the output remains the same

library(httptest)
library(testthat)

with_mock_api(
  {
    test_that("Output is producted correctly", {
      local_edition(3)
      expect_snapshot_value(
        download_scrobbles(.limit1 = TRUE),
        style = "deparse")
    })
  }
)

However, since testthat doesn't have access to my .Renviron file it fails with

'LASTFM_API_USERNAME' and/or 'LASTFM_API_KEY' environment variables are not set.
         Set them with 'Sys.setenv() or pass these variables explicitly.

I cant pass these parameters explicitly because then they would get checked into git and reveal the username and api key.

How can I either:

  1. Give testthat access to my local .Renviron file when run interactively (I'll skip the test when non-interactive), or
  2. Provide a .Renviron file to testthat in a way that doesn't require checking something into git or being built by R CMD BUILD, or
  3. Any other option I haven't considered?
like image 263
Conor Neilson Avatar asked Mar 24 '26 01:03

Conor Neilson


1 Answers

I was able to find an answer to this. If you just supply a fake password to the test it throws an error because it cant find the mocked files:

with_mock_api(
  {
    test_that("Output is producted correctly", {
      local_edition(3)
      expect_snapshot_value(
        download_scrobbles("condwanaland", "mocked", .limit1 = TRUE),
        style = "deparse")
    })
  }
)
Error: GET http://ws.audioscrobbler.com/2.0/?method=user.getRecentTracks&user=condwanaland&limit=1000&api_key=mocked&format=json&page=1&from=0 
(ws.audioscrobbler.com/2.0-699785.json)

However, the last part of that error (ws.audioscrobbler.com/2.0-699785.json) tells you the file name that httptest is looking for. By renaming the existing json file to match the expected one, the test passes.

like image 154
Conor Neilson Avatar answered Mar 26 '26 15:03

Conor Neilson



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!