Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add: verifyInputMessage for mock-session #3791

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

stefanedwards
Copy link

"Proof of concept"

Added methods to mock-session for verifying that specific calls to session$sendInputMessage were performed. Note: Before merging, these methods should be expanded to include session$sendCustomMessage and session$sendBinaryMessage!

This suggestion is inspired by how mocked classes in C# with Moq behave; that the mock itself is able to verify whether a given call was performed. By allowing mock-session to verify (upon request, naturally) it makes it easier to write unit tests of Shiny update methods, as the developer doesn't have to write boilerplate code. See e.g. following examples from tests/testthat/test-update-input.R:

Before:

createModuleSession <- function(moduleId) {
    session <- as.environment(list(
      ns = NS(moduleId),
      sendInputMessage = function(inputId, message) {
        session$lastInputMessage = list(id = inputId, message = message)
      }
    ))
    class(session) <- "ShinySession"
    session
  }

  sessA <- createModuleSession("modA")

  updateRadioButtons(sessA, "test1", label = "Label", choices = letters[1:5])
  resultA <- sessA$lastInputMessage

  expect_equal("test1", resultA$id)
  expect_equal("Label", resultA$message$label)
  expect_equal("a", resultA$message$value)
  expect_true(grepl('"modA-test1"', resultA$message$options))
  expect_false(grepl('"test1"', resultA$message$options))

After:

  session <- MockShinySession$new()
  updateRadioButtons(session, "test1", label = "Label", choices = letters[1:5])
  session$verifyInputMessage("test1",
    expect_equal(.$label, "Label"),
    expect_equal(.$value, "a"),
    expect_true(grepl('"mock-session-test1"', .$options)),
    !expect_false(grepl('"test1"', .$options)) ## negate returned FALSE from expect_false
  )

The verifyInputMessage has built-in support for the testthat-package, without depending on it. Calling verifyInputMessage is enough in a test_that:
Before:

test_that("session supports sendInputMessage", {
  session <- MockShinySession$new()
  session$sendInputMessage(inputId=1, message=2)
  expect_true(TRUE) # testthat insists that every test must have an expectation
})

After (with actual testing):

test_that("session supports sendInputMessage", {
  session <- MockShinySession$new()
  session$sendInputMessage(inputId=1, message=2)
  session$verifyInputMessage(1, . == 2)
})

As noted initially, these methods should be implemented for sendCustomMessage and sendBinaryMessage before including, and I will gladly do this (letting the three methods use the same routine, somehow).

@CLAassistant
Copy link

CLAassistant commented Mar 14, 2023

CLA assistant check
Thank you for your submission! We really appreciate it. Like many open source projects, we ask that you sign our Contributor License Agreement before we can accept your contribution.
You have signed the CLA already but the status is still pending? Let us recheck it.

New manner for testing the contents of `message`
when unit testing methods that use `sendInputMessage`.

Similar methods should be implemented for session$sendCustomMessage and session$sendBinaryMessage.
@stefanedwards stefanedwards marked this pull request as ready for review March 16, 2023 07:30
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants