1

I am having a problem while mocking a method that is being called in another method.

For example: Below in my main class.

class Trial extends TrialTrait {

  def run(): String ={
    val a = createA()
    val b = a.split(" ")
    val c = b.size
    val d = c + " words are there"
    d
  }

  def createA(): String = {
    var a = "above all the things that have been done, one thing remained in silent above all the things that have been done one thing remained in silent above all the that "
    a
  }
}

Below is my mock code.

class TryMock4 extends FunSuite with BeforeAndAfterEach with MockFactory {

  val trial = new Trial
  val st = stub[TrialTrait]

  test("Mocking the DataFrame") {
    val input = "above all the things that have been done, one thing remained in silent above "
    (st.createA  _).when().returns(input)
    val expected = "14 words are there"
    val actual = st.run()
    Assert.assertEquals(expected,actual)
  }
}

What I am trying to do is, passing mocking data to createA and use that in the run method.

But, it is giving null value after running the run method.

Could you please suggest how it can be achieved?

  • I don't think you can do it with ScalaMock. But you can do it with [Mockito](https://site.mockito.org/) using [`spy`](http://javadoc.io/page/org.mockito/mockito-core/latest/org/mockito/Mockito.html#spy-T-). But actually that fact that you need to mock an inner method to test is a sign of some wrong design. So I strongly suggest first consider refactoring your code. – SergGr Jan 22 '19 at 23:39
  • Thank you for the reply @SergGr. Can you please let me know how we can do it with Mockito using spy.I would appreciate if you can provide a sample code.. – Aswanikumar Jan 23 '19 at 07:07
  • Aswanikumar have you read the documentation I linked (the second link)? Have you tried that? Where exactly is your problem with `spy`? – SergGr Jan 23 '19 at 17:20

1 Answers1

1

I don't think you need a mock in this case, just a regular override should suffice.

class TrialTest extends FlatSpec with Matchers {
  behavior of "Trial"

  it should "count words" in {
    val input = "above all the things that have been done, one thing remained in silent above "

    val trial = new Trial {
      override def createA(): String = input
    }

    val expected = "14 words are there"
    val actual = trial.run()
    actual should be (expected)
  }
}

However, should you really want to use a mock here, it's possible with scalamock. You can define our own class that makes part of the class final (the bit you don't want to mock), see below:

class TrialTestWithMock extends FlatSpec with Matchers with MockFactory {
  behavior of "Trial"

  it should "count words" in {
    val input = "above all the things that have been done, one thing remained in silent above "

    class FinalTrial extends Trial {
      final override def run(): String = super.run()
    }

    val trial = mock[FinalTrial]

    (trial.createA _).expects().returning(input).anyNumberOfTimes()
    val expected = "14 words are there"
    val actual = trial.run()
    actual should be (expected)
  }
}
Philipp
  • 967
  • 6
  • 16