Testing local scoped object with mockito without refactoring - java

Say I have the following code:
public class ClassToTest
{
AnotherClass anotherClass;
public void methodToTest( int x, int y )
{
int z = x + y
anotherClass.receiveSomething( z );
}
}
public class AnotherClass
{
public void receiveSomething( int z ) {.. do something.. }
}
I want to make assertion on the value of the variable z. How do I do this without refactoring? Variables x, y, and z could be some other Java class types, and I just used "int" for simplicity.

You can write the following. Of course dependency injection and test method might change depending on your current implementation and/or your test scenarios.
#RunWith(MockitoJUnitRunner.class)
public class ClassToTestTest {
#Mock AnotherClass anotherClass;
#InjectMocks ClassToTest classToTest;
#Test public void ensure_that_value___Z___is_passed_to___AnotherClass() {
classToTest.methodToTest(1, 2);
verify(anotherClass).receiveSomething(eq(3));
}
}
Written with Mockito 1.9.5-rc1 in mind.
Also instead of using the eq matcher you can instead use an ArgumentCaptor, which will capture values or value references (in case of objects). You'll be able to perform additional assertions on the captured value(s). For example using Truth or FEST-Assert.
This could look like :
#RunWith(MockitoJUnitRunner.class)
public class ClassToTestTest {
...
#Captor ArgumentCaptor<List<Z>> listCaptor
#Test public void ensure_that_list_with_value___Z___is_passed_to___AnotherClass() {
// given
// when
...
// then
verify(anotherClass).receiveList(listCaptor.capture());
assertThat(listCaptor.getValue()).contains(Z);
}
}
Cheers,

Related

JUnit Mockito object initialization in method

I am using Mockito's when and thenReturn function and am wondering if there's a way for the object inside to be initialized in the test functions. So for example if I had:
public class fooTest {
private Plane plane;
private Car car;
#Before
public void setUp() throws Exception {
Mockito.when(Car.findById(eq(plane.getId()))).thenReturn(plane);
}
#Test
public void isBlue() {
plane = new Plane();
plane.setId(2);
Plane result = Car.findById(car);
assertEquals(Color.BLUE, result.getColor());
}
}
Obviously the above code doesn't work because it throws a null pointer exception but the idea is to initialize the plane object in every test function and have mockito's when use that object. I suppose I could put the when line in every function after the Plane object has been initialized and set but that makes the code look very ugly. Is there a simpler way to do it?
Since I dont know your Plane or Car class, am going to make some assumptions in the test class.
I dont know what you are trying to test, If you are trying to test Car , you shouldnt ideally mock your class under test.
Any way you can do something like this in your setUp method.
public class fooTest {
private Plane plane;
#Mock
private Car car;
#Before
public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
plane = new Plane();
plane.setId(2);
plane.setColor(Color.BLUE);
Mockito.when(car.findById(eq(plane.getId()))).thenReturn(plane);
}
#Test
public void isBlue() {
// There is no point in testing car since the result is already mocked.
Plane result = car.findById(2);
assertEquals(Color.BLUE, result.getColor());
}
}

JMockit - Partial mocking and mocked parent

I would like to test (using JMockit) a class that looks like this:
class MyClass extends ComplexParentClass {
public void testedMethod() {
...
}
private int complexPrivateMethod() {
...
}
}
I can't change the class. The problem is that the ComplexParentClass has a complex constructor, which makes it hard to test. So I would like to mock the parent class. I would also like to mock the complex private method. But is something like that even possible?
I tried the following:
class MyClassTest {
#Tested
MyClass myClass;
// mock the parent
#Mocked
ComplexParentClass complexParentClass;
#Test
public void test() {
new Expectations(myClass) {{
// partially mock the private method
Deencapsulation.invoke(myClass, "complexPrivateMethod"); result = 0;
}};
myClass.testedMethod();
}
}
This leads to an "already mocked" exception though.
Does anybody have an idea how to approach this?
Have you tried using MockUps? Something like this would mock complexPrivateMethod only:
#Test public void test() {
new MockUp<ComplexParentClass> () {
#Mock private int complexPrivateMethod() { return 0; }
};
//do something with MyClass
}

How mock jcabi annotation parameters

I have some code like below.
#RetryOnFailure(attempts = Constant.RETRY_ATTEMPTS, delay = Constant.RETRY_DELAY, unit = TimeUnit.SECONDS)
public void method() {
// some processing
//throw exception if HTTP operation is not successful. (use of retry)
}
The value of RETRY_ATTEMPTS and RETRY_DELAY variable come from a separate Constant class, which are int primitive. Both the variable are defined as public static final.
How can I override these values while writing the unit testcases. The actual values increases running time of unit testcases.
I have already tried two approach: Both did not work
Using PowerMock with Whitebox.setInternalState().
Using Reflection as well.
Edit:
As mentioned by #yegor256, that it is not possible, I would like to know, why it is not possible? When these annotations get loaded?
There is no way to change them in runtime. What you should do, in order to make your method() testable is to create a separate "decorator" class:
interface Foo {
void method();
}
class FooWithRetry implements Foo {
private final Foo origin;
#Override
#RetryOnFailure(attempts = Constant.RETRY_ATTEMPTS)
public void method() {
this.origin.method();
}
}
Then, for test purposes, use another implementation of Foo:
class FooWithUnlimitedRetry implements Foo {
private final Foo origin;
#Override
#RetryOnFailure(attempts = 10000)
public void method() {
this.origin.method();
}
}
That's the best you can do. Unfortunately.

Testing functions in class which expects string in constructor using Mockito

I have the following class and want to write unit test for it. Below is the class for full reference. X is POJO
public class StatusTable {
private P tableData;
private Q tableDefinition;
public StatusTable(final List<X> xList,
final A a,
final B b)
throws URISyntaxException {
setTableDefinition(a, b);
setTableData(xList, b, a);
}
private void setTableDefinition(final A a,
final B b) {
//some code
}
public void setTableData(final List<X> xList,
final B b, final A a)
throws URISyntaxException {
for (X sfm : xList) {
//some code
}
}
}
Being new to unit testing, I have very minimal idea of how to test but here is a thought. Please correct me wherever incorrect.
public class StatusTableTest {
private StatusTable statusTable;
#Mock
private A mockA;
#Mock
private B mockB;
#Mock
private X mockX;
public void setUp() {
stub(mockX.getSomeValue()).toReturn(?); //want to return any string
stub(mockX.getSomeAnotherValue()).toReturn(?); //want to return any integer
//Similarly mock other functions retuning
this.statusTable = new StatusTable(xList, mockA, mockB,);
}
public void setTableDefinitionTest() {
//test the code
}
}
I have a few doubts:
a) Am I doing it correctly? Should the X be mocked?
b) Is there anyString() kind of functionality in Mockito or should I use something else?
a) It is hard to tell without actual code. You can mock individual X values or whole List of X.
b) Your end result is based on expected values, so you should not return anyString(), but some specific String. So you can verify that your code behaves correctly for this particular String. I.e. assert that table contains single cell with "abc" text if passed list with one X returning "abc".
Depending on what you want to mock.
You can mock any call to your class and return any value or spy on an existing class and overload a call with your mocked call.
For instance
mockedX = Mockito.mock(X.class);
Mockito.when(mockedX.someFunction("1")).thenReturn(someAnswer);
or:
X x = new X();
spiedX = Mockito.spy(x);
Mockito.answer(some answer).when(spiedX).someFunction("1");
Remember ... the mocked class will return what you are mocking.
If you create a mock like this:
Mockito.when(mockedX.someFunction(Mockito.anyString())).thenReturn("A");
then on every call someFunction() will return "A".

Static methods are sort of code smell?

I am recently working on TDD with JUnit and Mockito. For some purpose within a method, I am using an Util class (an utility class having methods in project context). The thing is what I am facing is how to mock such classes in Mockito. I am not able to find as such implementation regarding static methods in Mockito. Some suggest using PowerMock on top of Mockito but wouldn't that replace my JunitMockitoRunner?
The way I am using the static function is:
public void doSomething(int x){
//Some code
Y y = Util.someStaticMethod(x);
//Some more code
}
EDIT : Also I read somewhere that using static methods is a code smell and is a sign of bad design. So how should I be refactoring the design and what advantages will I be having as a result?
How should I be refactoring the design and what advantages will I be having as a result?
Well, if you need to mock the static utility method, then make it an instance method of an injectable object, so that you can inject a mock implementation of this object. The advantage is that it makes your code more testable:
public class Util {
public Y someInstanceMethod(X x) {
...
}
}
public class ClassToBeTested {
private Util util;
public ClassToBeTested(Util util) {
this.util = util;
}
public void doSomething(int x){
//Some code
Y y = util.someInstanceMethod(x);
//Some more code
}
}
public class ClassToBeTestedTest {
public void testDoSomething() {
Util mockUtil = mock(Util.class);
ClassToBeTested t = new ClassToBeTested(mockUtil);
when(mockUtil.someInstanceMethd(3)).thenReturn(...);
...
}
}
That's the main selling point of dependency injection: it makes your code testable.
I do something like that for mocking static Util classes with jMockit.
public class UtilsTest {
#After
public void teardown() {
Mockit.restoreAllOriginalDefinitions();
}
#Test
public void testMyUtil() {
Mockit.setUpMocks( MockUtil.class );
}
}
#MockClass(realClass=Util.class)
public class MockUtil{
#Mock
public static MySpecialClass someStaticMethod(int x) {
return Mockito.mock(MySpecialClass.class);
}
}

Categories

Resources