1

i.e. two classes:

class A{
  public int getValue(){
    return 5;
  }
}

class B{
  public int getValue(){
    A a = new A();
    return a.getValue();
  }
}

Now I want to write a test for class B, but I want to mock class A for that test. The question is: how?

(This snippet is only a simpler version of my problem, please don't take care returning 5 or smth)

Marcin Petrów
  • 1,447
  • 5
  • 24
  • 39

3 Answers3

3

Probably there are some tricky way to do so, but in brief, the way you write B does not favor mocking. Instead of instantiating A in B, try to inject A to B

Consider changing it to

class B {
  private A a;
  public void setA(A a) {
    this.a=a;
  }
  public int getValue(){
    return a.getValue();
  }
}

You can even initialize a by private A a = new A(), but providing a setter allow you to inject a mock for testing.


Edit: If there are difficulties in rewriting B to make it unit test friendly, you still can make use of mocking framework that will do bytecode manipulation, like Powermock. Here is an example of achieving what you want:

http://code.google.com/p/powermock/wiki/MockConstructor

Adrian Shum
  • 38,812
  • 10
  • 83
  • 131
  • If the setter is needed for test only, it should be package protected. Then you can be nearly sure, that nobody change the A instance. – agad Sep 10 '13 at 10:02
  • Ok, but I don't want to change that code... I want to write test for it:) By the way this snippet is just a very simple explanation of my problem – Marcin Petrów Sep 10 '13 at 10:02
  • @agad: Yes, if it is aimed only for testing, we should make it protected. However I believe if the class is properly rewritten, the injection setter should be something public anyway :) – Adrian Shum Sep 10 '13 at 10:54
  • @Mart.ini : I believe it is always better to write code that is unit test friendly. However, if you really insist to make mocking happen in the original case in your post, you may take a look in Powermock, for which it actually alter the class of `A` so it should be possible to do such kind of mocking (sorry I haven't had chance to make use of Powermock before therefore cannot give you an example) – Adrian Shum Sep 10 '13 at 10:57
  • 1
    @Mart.ini found you a page of Powermock that is close to your case, please see edit – Adrian Shum Sep 10 '13 at 10:59
1

Mocking can be done using instance variable and have a setter for the same.

Below two links possibly help you to the above things you are trying to do

JUnit mocking with Mockito, EasyMock, etc How to mock local variables in java?

Community
  • 1
  • 1
Jayaram
  • 1,715
  • 18
  • 30
0

Mock class use to get data which required to test other class functionality. In this case no use of mock class for class A since it just returning 5. but if it is business logic inside class A, you should use a mock class. create a new class and add same method names in original class and without doing any logic just return some value from there.

Ruchira Gayan Ranaweera
  • 34,993
  • 17
  • 75
  • 115