Easy mock behaviour while requested - java

I was thinking, is it possible to mock whole object behavior with EasyMock, but in a way that once declared mock with all expected values and results is used several times without caring about the order of the requests ?
The purpose for this is to create an instance of mock for example in JUnit test #BeforeClass and use it in several #Test methods.
Thank you in advance for any input,
Regards,
P.

If you are not interested in verifying calls to the mock, and your only aim is to ensure that whenever a specific method on the mock is called, it will always return the same desired result, you can configure it using andStubReturn(), e.g.
expect(mock.getMeaningOfLifeUniverseAndEverything()).andStubReturn(42);

I think you're really wanting two things:
The ability to use mocked methods out of order, which is the default easymock (non-strict mode),
The ability to use mocked methods any number of times.
You do the latter like this:
expect(someMock.someMethod()).anyTimes().andReturn(someValue);
If your method will get different arguments each time it is called, you can use the anyObject() method to ignore the provided argument.

Related

How do I manipulate an argument with mockito

I am using junit to run a few unit tests. One of these calls a method in an object that I mock using mockito like;
#Mock
private MyClass myClass;
I then set up mockito to do something like
Mockito.when(myClass.foo(Mockito.any()).thenReturn(bar);
Now myClass.foo actually takes another one of my classes (say class Person) as an argument and what I would like to do is something like this
Mockito.when(myClass.foo(Person parson)).thenDo(person.setName("Name")).thenReturn(bar);
That is of course pseudo code but I hope it illustrates what I am trying to do. Is this possible?
You need to use thenAnswer or its twin doAnswer method.
See Mockito : doAnswer Vs thenReturn
You should use thenReturn or doReturn when you know the return value at the time you mock a method call. This defined value is returned when you invoke the mocked method.
Answer is used when you need to do additional actions when a mocked method is invoked, e.g. when you need to compute the return value based on the parameters of this method call.
If your answers become too complicated, consider using a fake instead of a mock.
In this case if your goal is to set field of Person object you can do that before or after the line:
Mockito.when(myClass.foo(Mockito.any()).thenReturn(bar);
doAnswer() would help do operations based on input, but operations would be performed on copy of arguments not the original arguments.

Unit testing save methods when return type is void

Is there any way to write unit tests for save methods in DAO layer when return type is void? I'm using Log4j, Junit in spring boot project.
I've tried many ways to assert them. But since they aren't returning any value i wasn't able to assert them.
If the method is void, then it has side-effects, otherwise it would be a no-op.
So you call the method, then check if the desired side-effect happened.
E.g. setFoo(7) should mean that getFoo() returns 7, though unit testing simple getter/setter methods is a waste of time.
It is common to use mock objects to detect the side-effects, but it all depends on what the expected side-effect is. See: What is the purpose of mock objects?
There are several ways to unit test a method that returns void.
Change the method so that it returns a value even though you don't use that value. This is NOT the best way, but I note it here for completeness.
The method likely changes the state of the object in some way. A file was saved, a value was stored somewhere, parameters have been changed, etc. So check the values that should have been changed. You can read back a saved file, a changed variable, data in a test database, etc.
Mock objects can be used to determine if a method was called and what the behavior was. There are a number of mock object frameworks for Java, including Easy Mock, JMockit and Mockito. How to use a mock framework is beyond the scope of this answer, but I did include links to the various sites for your reference.
If bad inputs are given to the method it may throw an exception. It is a good idea to do this to test the error handling of your methods.
According to your comments you need to write an unit test for a save method. Try this example code,
#Autowired
private EmployeeDAO employeeDAO;
#Test
public void whenValidEmployee_thenShouldSave()
{
EmployeeEntity employee = new EmployeeEntity("1", "Department Name", "Role"); //id, department name and role are passing as constructor parameters
employeeDAO.save(employee);
List<EmployeeEntity> employees = employeeDAO.findAll();
//Assert
Assert.assertEquals(employee.getId(), employees.get(0).getId());
}
Writing a testable code is important as a developer in modern days. You should understand that a method with void, is bad for a single reason.it is not testable by any means. i would suggest you below actions to take
Improve your code with a relevant return type.
It's worth applying DbUnit, rather than applying just Junit to test
your DAO layer.
#Teguwih

Mockito - wanted but not invoked - interface.method()

I am running a few tests right now in which I mock one of my interfaces like this:
interface = mock(InterfaceView.class);
I then try to verify one of my methods off of this interface but continually get an error:
verify(interface).someMethod(objList);
The error I get here is Wanted but not invoked: interface.someMethod(...)
, Actually, there were zero interactions with this mock.
mockito is actually telling you that your expectation was not met. You implemented your test to expect a call to that method (that's what verify does, unless you parametrize it to verify that never gets called), but your tested instance does not call it with the given parameters.
verify(interface).someMethod(objList) It's verification that someMethod was invoke exactly one time.
So if there is no interaction, then you shouldn't use this method :D
Note:
If You want to verify that object didn't have any interaction, then use:
Mockito.verifyZeroInteractions(obj)

PowerMock, how to make a static method return value more than once?

This may be a simple question, but I could not find an answer with reasonable search.
I am trying to make a static method return a value more than once in multiple tests. I fail to achieve this with the mocked static method with PowerMock. To put this simply I have a JUnit test #BeforeClass like this
#RunWith(PowerMockRunner.class)
#PrepareForTest(StaticStuff.class)
public class MyTest extends TestCase {
#BeforeClass
public static void init() {
// Mock some stuff
PowerMockito.mockStatic(StaticStuff.class);
Mockito.when(StaticStuff.get()).thenReturn("something");
}
}
Now, this works for the first test accessing the static method, but the rest will receive 'null' (update: or any other value that the "real" method would return). I can fix the problem simply changing the #BeforeClass to #Before, thus making the static mock be recreated for every test. But afaik, this is not the correct way to do this. For this particular case this will do, but I believe there should be a way to provide information that the method may be called "any times".
Actually I understood from the documentation that the same value should be returned "infinite times by default" (but it doesn't. From Mockito documentation: 'Once stubbed, mocked method will always return stubbed value regardless of how many times it is called.'). Also I would expect that stating the amount of calls should be something this simple (but it isn't):
Mockito.when(StaticStuff.get()).thenReturn("something").times(10);
Maybe I am just missing something?
The tests should be independent from each other. If you use JUnit, the order of the tests is not determined at all (see https://github.com/junit-team/junit/wiki/Test-execution-order). I think creating mocks in #BeforeClass is actually a bad practice, since it can cause that the tests are depending on each other. So I would simply recommend to use #Before method to initialize all mocks, and use #BeforeClass only, if you prepare something really common for the tests (like a connection pool or something like that).

Correct way to design and test this class

I am developing an interpreter and want to do internal testing of an "execute" method that interprets a model. The execute method doesn't have input or output, so the only way to test the method (at least from what I know) is to mock the internal method calls to see that they are executed in the right order.
Currently I have the following classes:
ExecutableInstance - model class that can be executed.
ExecutableInstanceFactory - singleton class (implemented as an enum) that creates executable instances, with different methods depending on the parameters it is given.
ModelAnalyzer - singleton class that contains methods to analyze the model
The interpreter calls the execute() method of the ExecutableInstance class, which then calls the ModelAnalyzer to understand the internal executable instances in the model. It then creates new ExecutableInstances using the ExecutableInstanceFactory and then calls their execute() method depending on how the model is defined.
My idea is to mock the ExecutableInstanceFactory class so that it returns mock ExecutableInstaces which I can then test for execution order. But this would mean that I have to inject the ExecutableInstanceFactory into the ExecutableInstance. Since it is a singleton, it would be dumb and stupid to pass it as a parameter. I thought of using Google's Guice for DI... but I'm stuck trying to do this.
Is my direction correct? If so, how should this be implemented?
I would make a few smaller methods out of this execute method. For example - one method for parsing which returns something to the execute method, then another one which does something with the returned data and returns other data etc. Then you would not have to test the Execute method, only the smaller ones. This will also allow you to detect bugs easier.
The execute method doesn't have input or output
So behaviour should be verified on the class' collaborators (use mocks).
Since it is a singleton, it would be dumb and stupid to pass it as a parameter.
The fact that you have problems testing shows you flaws in your design. Get rid of a singleton and inject the collaborators.

Categories