2

I have the following code:

public class ABC { private double a; Other_object other_object; public ABC(int a, int[] b){ this.a=a; other_object=new Other_object(b); } ... public int method_1(){ return other_object.other_method(); } public int method_2(){ if(method_1()>0 && a>0) return 1; else return 0; } 

}

I've created the following mock object: ABC a=mock(ABC.class); Mockito.when(a.method1()).thenReturn(0);

I cannot set a value for "int a". I tried to create a setter function in ABC, and mocking it, but it doesn't work. I would like to know why mocking the setter function doesn't work how can I mock this value (int a)?

3
  • 2
    Why would you need to set a value for int a in a mock object? A mock object doesn't use any of the instance variables it has. All its methods do nothing, other than what you tell the mock to do. The value of int a is irrelevant. What are you trying to achieve? My little finger tells me that you're trying to test the mock. That's useless. All you will test is that mockito works as expected. Commented Mar 7, 2016 at 21:30
  • Yes, this pattern of thought often happens when the concept of mocks is misunderstood. A mock is a programmable stub that you use instead of real objects that your Code Under Test talks to so that it doesn't have to talk to real objects that pulls the whole world with it. This is a way to isolate your CUT. So if ABC is your CUT you should not mock that class. Commented Mar 8, 2016 at 5:45
  • Sorry for not being clear. I want to test method_2(). That's why I create mock object to give value to method_1(). I don't know what to do with value of int a. Is this a wrong way of testing it? Should I test the Other_object class first and then set values of ABC class in constructor? In this case will it be a unit test? Commented Mar 8, 2016 at 14:31

2 Answers 2

2

A mock is an object that "pretends" to do something. So the important thing about a mock is its behavior, not its state (because it doesn't really have much of a state). Of course you COULD let the mock react to a setter, store the value and then return it via the getter, for example via an Answer (I will not provide code for that), but I can almost guarantee that this will NOT be a good solution for whatever problem you are having.

Mocking is for when you don't actually need a real object, but want to test another object that depends on it. So your mock object is just a way to test something else.

For example, let's assume you are testing your class MyClass. Is has a method like this...

public int doSomething(ABC abc) { return abc.method_1 * 2; } 

If you do not want to use a real "ABC" object for whatever reason, you can mock it. Your test of your MyClass would look like this (condensed)...

@Test public void doSomething_must_return_2_when_method_1_returns_1() { ABC abcMock = Mockito.mock(ABC.class); when(abcMock.method_1()).thenReturn(1); Assert.assertEquals(2, myClass.doSomething(abcMock) ); } 

If you actually need to store some value in the mock, then you either don't need a mock or your test case is far to complex. Remember: A test should test ONE thing. It should only have ONE point of failure. If you have multiple test cases, use multiple methods, not one. If your object needs to do more than basic "call method, give result" a mock might not be the correct tool.

But in your example, your a is constant for any instance of ABC. You initialize it in the constructor. So for any mock you create, your a is also constant. So, if you needed to mock method_2, then you also already know the result... No need to set a here anywhere. If you want to mock ABC, you already know a and thus know what the methods would return on a real ABC. No need for the mock to actually store a and actually work with it.

Edit: IF you want to test method_2(), then what you want to test is class ABC itself. It makes absolutely no sense to create a mock of class ABC then, because all you would test would be this "fake" ABC, but not the real one, so you would end up as clever as before, with no knowledge gained about ABC. So, if you want to test your ABC.method_2(), then create an actual instance of ABC...

ABC abcToTest = new ABC(...); Assert.assertEquals(..., abcToTest.method_2()); 

No need (or chance) for mocking here.

Sign up to request clarification or add additional context in comments.

2 Comments

Sorry for not being clear. I want to test method_2(). That's why I create mock object to give value to method_1(). I don't know what to do with value of int a. Is this a wrong way of testing it? Should I test the Other_object class first and then set values of ABC class in constructor? In this case will it be a unit test?
If you want to TEST method_2(), then you cannot MOCK the class ABC. You cannot create a fake ABC, if you want to test the REAL one, where would be the point? All you would test would be your fake ABC. So, in your case, you don't need mocking. Simply create a new instance of ABC (ABC toTest = new ABC(...);) and test that.
1

Hope below code useful for you

@Mock SampleClass sampleClass; ReflectionTestUtils.setField(sampleClass, "variableName","ISO-8859-1"); 

1 Comment

If a method of SampleClass uses variableName variable and you do a doCallRealMethod on that method, will it work? Or you get npe?

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.