membersound
membersound

Reputation: 86845

How to mock a full method?

It is possible to mock a full method? Or would I have to mock every single service call inside that method?

Here is a (silly) example:

class Foo {
   void update() {
      service1.do();
      service2.do();
      //...
   }
}

class Bar extends Foo {

   void save() {
      super.update();
      // doSometing that I want to test.
   }
}

I want to test Bar.save() , and I want to mock everything inside super.update() without having to mock every service itself. Is that possible?

Upvotes: 3

Views: 111

Answers (2)

Adam Adamaszek
Adam Adamaszek

Reputation: 4044

In your case it seems that Bar extends Foo.

Because of that it's more difficult to mock it with a framework, yet you could override update() in your test instead:

Bar testBar = new Bar() {
@Override
  void update() {
  // do nothing
  }
}

assertSomething(bar.save());

But... @smas is right, needing to do it this way is a code smell, that indicates you should break the is-a into has-a relationship, then mocking will be a breeze:

class Bar {

  private Foo foo;

  public Bar(Foo foo) {
    this.foo = foo;
  }

  void save() {
    foo.update();
  }

}

And your test:

Bar bar = new Bar(mock(Foo));

assertSomething(bar.update());

Upvotes: 1

lukastymo
lukastymo

Reputation: 26819

Your Bar class is-a Foo. Bar has inherited update method from Foo. So you shouldn't mock the method from the class under test. It is much nicer to choose one of this:

  • Consider using composition, then it would be natural way to mock it.
  • Inherit from FooTest. You have tests for Foo, right? You have @Before setup which mock all services there. Reuse it.

Upvotes: 2

Related Questions