On 02/01/2017 02:46 PM, Ramiro Barrantes wrote:
Hello,

I have a function that applies to an S4 object which contains a slot called 
@analysis:

function calculation(myObject) {
  tmp <- myObjects@analysis
  result <- ...operations on analysis...
  return result
}

I am writing a unit test for this function.  So I was hoping to create a mock 
object but I can't figure out how to do it:

test_that("test calculation function", {
  mockMyObject<- mock(?????)  #I am not sure what to put here
  r<-calculation(mockMyObject)
  expect_true(r,0.83625)
})

How can I create a mock S4 object??

I don't know of a convenient way to create a mock with functionality like mocks in other languages. But here's a class

  .A = setClass("A", contains="integer")

This creates an instance that might be used as a mock

   mock = .A()  # same as new("A")

but maybe you have an initialize method (initialize methods are very tricky to get correct, and many people avoid them, using plain-old-functions to form an API around object creation; the plain-old-function finishes by calling the constructor .A() or new("A")) that has side effects that are inappropriate for your test, mimicked here with stop()

  setMethod("initialize", "A", function(.Object, ...) stop("oops"))

our initial attempts are thwarted

> .A()
Error in initialize(value, ...) : oops

but we could reach into our bag of hacks and try

  mock = .Call(methods:::C_new_object, getClassDef("A"))

You would still need to populate slots / data used in your test, e.g.,

  slot(mock, ".Data") = 1:4

This is robust to any validity method, since the validity method is not invoked on direct slot assignment

  setValidity("A", function(object) {
      if (all(object > 0)) TRUE else "oops2"
  })

  slot(mock, ".Data") = 0:4  # still works

So something like

  mockS4object = function(class, ..., where=topenv(parent.frame())) {
      obj <- .Call(
          methods:::C_new_object,
          getClassDef(class, where=where)
      )

      args = list(...)
      for (nm in names(args))
          slot(obj, nm) = args[[nm]]

      obj
  }
  mockS4object("A", .Data=1:4)

Mock objects typically have useful testing properties, like returning the number of times a slot (field) is accessed. Unfortunately, I don't have anything to offer for that.

Martin



Thanks in advance,
Ramiro

        [[alternative HTML version deleted]]

______________________________________________
R-help@r-project.org mailing list -- To UNSUBSCRIBE and more, see
https://stat.ethz.ch/mailman/listinfo/r-help
PLEASE do read the posting guide http://www.R-project.org/posting-guide.html
and provide commented, minimal, self-contained, reproducible code.



This email message may contain legally privileged and/or...{{dropped:2}}

______________________________________________
R-help@r-project.org mailing list -- To UNSUBSCRIBE and more, see
https://stat.ethz.ch/mailman/listinfo/r-help
PLEASE do read the posting guide http://www.R-project.org/posting-guide.html
and provide commented, minimal, self-contained, reproducible code.

Reply via email to