I am currently using R6 classes in a project.
I would like to write unit tests that also test the functionality of private methods that I am using (preferably by not going through the more complicated public methods that are using these private methods).
However, I can't access seem to access the private methods.
How do I best do that?
Thanks!
To test private methods, you just need to test the public methods that call them. Call your public method and make assertions about the result or the state of the object. If the tests pass, you know your private methods are working correctly.
Why We Shouldn't Test Private Methods. As a rule, the unit tests we write should only check our public methods contracts. Private methods are implementation details that the callers of our public methods aren't aware of. Furthermore, changing our implementation details shouldn't lead us to change our tests.
R6 is an implemention of encapsulated object-oriented programming for R, and is a simpler, faster, lighter-weight alternative to R's built-in reference classes. This style of programming is also sometimes referred to as classical object-oriented programming. Some features of R6: R6 objects have reference semantics.
When an R6 object is cloned, the resulting object's methods will have a self that refers to the new object. This works by changing the enclosing environment of the method in the cloned object. In contrast to class methods, you can also add regular functions as members of an R6 object.
Here is a solution that does not require environment hacking or altering the class you want to test, but instead creating a new class that does the testing for you.
In R6
, derived classes have access to private
Methods of their base classes (unlike in C++
or Java
where you need the protected
keyword to archieve the same result). Therefore, you can write a TesterClass
that derives from the class you want to test. For example:
ClassToTest <- R6::R6Class(
private = list(
privateMember = 7,
privateFunction = function(x) {
return(x * private$privateMember)
}
)
)
TesterClass <- R6::R6Class(
inherit = ClassToTest,
public = list(
runTest = function(x = 5) {
if (x * private$privateMember != private$privateFunction(x))
cat("Oops. Somethig is wrong\n")
else
cat("Everything is fine\n")
}
)
)
t <- TesterClass$new()
t$runTest()
#> Everything is fine
One advantage of this approach is that you can save detailed test results in the TesterClass
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With