Mocking a method which contains a method that calls a REST API - java

I have two methods that basically look like this:
private void methodA() {
// Do stuff
methodB();
// Do stuff
}
private void methodB() {
// Do stuff
// Make a GET request for some data
// Do stuff depending on data returned from GET request
}
I want to write a JUnit test for methodA, the problem is that methodB will throw an exception because it is not able to process the data from the API call because there is none. Is there a way that I can mock the response of the API call to a nested function without using real data?
One thought I had was to put real data for the API call to retrieve. But then the test would fail later on if said data was removed.

The purpose of mocking is not to perform integration tests, but to mimic the behavior of components to test a single unit. I would suggest to either mock methodB as well, so that you would have control over data, that is "sent" by other service or mock the whole methodA, so that you don't have to mock every single method inside.

Related

Mockito, mission of method verify

Could you please explain a mission of mockito method verify? Documentation says, that this method checks, whether the method was called. But can you give an example when it is really useful? Usually in test method we invoke a method and then... check, that we have invoked it right now? Sounds weird.
To simplify... Let's say you are testing method A with certain parameters. What method A does is calls methods B, C and D.
With Mockito.verify you can test that methods B, C, D really are called. It even let's you specify more complex testing such as:
atLeast(1)
atMost(10)
It can really be useful when the method you are testing behaves differently based on parameters you call it with.
It goes like this:
public class UnderTest {
private Foo foo;
public UnderTest(Foo foo) { this.foo = foo };
public void bar() { foo.foo(); }
}
Now assume that you provide a mocked foo instance to UnderTest. And you want to be sure that foo.foo() is invoked when bar() is called.
Then you use verify() to ensure that the expected call took place.
In other words: tests need to verify method behavior. Ideally they do that by asserting on values returned by the method under test. But not all methods return something. Then you might verify your code by at least checking that certain expected calls on objects owned/passed to the class under test did occur. And then you need verify()!
This type of check is often performed just to make sure that specific object was used using specified parameters. Let's assume You are testing business service that performs some action and also some kind of audit trail is being stored in DB during this process.
Storing that kind of info in DB was already tested somewhere else (separate unit-tests or some kind of external library is used), so You do not need checking whether audit data was stored properly. For the sake of Your test-case the information that this method was called is sufficient. And that's the use case for 'verify' method.
Usually in test method we invoke a method and then... check, that we have invoked it right now? Sounds weird.
You don't verify that you invoked a test method. You verify that as a result of whatever that test did, some dependency (that you have replaced with a mock) was called.
So for example, when testing a password checker method, you want to assert that in addition to rejecting the incorrect password it also calls some auditing backend system to register the failed login attempt. Your mock object would stand in for that backend system, and you can use it to verify that it ended up being called (and also with the proper parameters).
Let's imagine that you have some DAO class which interacts with the database by plain JDBC. You have some method to write data in the database and want to unit test it. To do so, you probably mock Connection class. When you're writing in the database you will probably call commit method on this mock, but the return type of it is void, so you can't guarantee that that method invoked during your test. To solve such problems you can use verify.
Hope it helps!
Methods return either something or void.
In unit test, as a method returns something, generally you want to mock its result with a specific value and check that the flow of the tested method goes on as it should.
It makes sense as if a method to mock returns something, generally you need its results : either in the next statement of the tested method or in the result returned by the tested method.
As a method returns nothing (void), things are different : you cannot mock its result.
But you can assert that this method is invoked and with expected parameters.
For example imagine a PrinterService class to print documents
public class PrintService{
...
public void printMessage(String message){
os.print(message);
}
}
And suppose you need to isolate it during an unit test of another class.
Here the method to test :
public class PrintClient{
...
PrintService printService;
public void print(String message, PrinterParameters printerParameters...){
... // do some tasks
...
printService.print(message);
...
}
}
PrintService.print() returns nothing.
So in the unit test of PrintClient, you don't want to mock the result of PrintService.print() as it doesn't have.
You want just to check that it was invoked with the message argument passed to
to the PrintClient tested method.
#RunWith(MockitoJUnitRunner.class)
public class PrintClientTest{
#Mock
PrintService printServiceMock;
...
#Test
pubic void print(){
...
String message = "my message";
PrintClient printClient = new PrintClient(printServiceMock);
printClient.print(message, ...);
//
Mockito.verify(printServiceMock).print(message);
...
}
}

mocking in go. Is there an easy way?

I come from python and I have been looking for a way to write yests in go. I have come across a few things on SO but they all seem very cumbersome and verbose for something that shpuld be needed all the time.
I am typing on mobile now, will add code later if needed...but for example...
say i have a function that calls smtp.Send somewhere in the middle. how can I easily test this function?
Say i have another one that hits some outside api (needs mocking) and then takes the response and calls something like ioutil.Readall()...how could i make my way through this test function and mock the call to the api and then pass some fake response data when Readall is called?
You can do it by using an interface. For example let's say you have an interface called Mailer:
type Mailer interface {
Send() error
}
Now you can embed a Mailer object into the function that calls the Send method.
type Processor struct {
Mailer
}
func (p *Processor) Process() {
_ = p.Mailer.Send()
}
Now in your test you can create a mock Mailer.
type mockMailer struct{}
//implement the Send on the mockMailer as you wish
p := &Processor{
Mailer: mockMailer,
}
p.Process()
when p.Process reaches the Send method it calls your mocked Send method.

Junit testing method which returns nothing and has service call to other system

I have a method which does following.
public void callService(SomeObject someObject) {
// call helper class method and create a request XML
// scrub this XML using a local method and persist it in MongoDB
// call a 3rd party service using HTTP POST
// Recieve the response
// Persist the response in MongoDB and set in in somObject
// return
}
Now as part of development we have to write unit test cases for this method. I am new to Junit testing as well as mock objects. but when I googled and looked at the some other similar questions I understood that testing void method is little bit different than normal methods and I think my above method which special in some more way as I am clueless as to what and how to test for this method.
Can someone please give me pointer or any reference as to how I can unit test this method using Junit.
You'd probably want to use mocks to stand in for your Mongo connection and the third party service. It's easiest to use an existing mock framework, but this is the general concept.
Pretend that you post to this third party service by constructing a StuffToPost object and passing it to the post method on your ThirdPartyPoster. Then you can create a mock object as follows:
public class MockThirdPartyPoster implements ThirdPartyPoster {
private int count = 0;
private StuffToPost stuffToPost;
#Override
public void post(StuffToPost stuffToPost) {
this.count++;
this.stuffToPost = stuffToPost;
}
public int getCount() {
return count;
}
public StuffToPost getStuffToPost() {
return stuffToPost;
}
}
In your test, you'd construct this MockThirdPartyPoster and pass it to thingToTest.setThirdPartyPoster, then call your method. Once the method finishes executing, you can call getCount() on the mock to make sure that you POSTed once and only once, and call getStuffToPost() to examine the StuffToPost object and make sure that it is correct. You'd do something similar for Mongo persistence as well.
That calls for a lot of boilerplate; mock frameworks like Mockito or EasyMock exist to solve that problem.

Does mockito store actions when I want to test a complicated method

I'm new to mockito. It's simple and cool framework to use (It made me love testing :) ).
I'm testing a complicated method :
In this method, I call a service only if data change.
public void testMyFacadeMethod() {
....
If (dataChanged) {
myService.callServiceMethod();
}
}
In my test method : I prepare my mocks then I change data and I call
verify(myService).callServiceMethod();
everything is Ok and my test pass.
in the same test method I recall my facadeMethod so myService.callServiceMethod must not be called (because my data doesn't change).
Test fails :
verify(myService).callServiceMethod();
myFacadeMethod() <== tested method
verify(myService, times(0)).callServiceMethod(); <= tell me that this method is called once
My question is : does mockito store the number of times that method is called until this line ? so the first call doesn't reset the counter ?
For me, the second call of verify method will only count the number of call after the first call of verify (I'm complicating life I know :p )
Thank you and sorry for my english.
Do you recommend any test ebook to learn the art of testing ?
You can use Mockito.reset to reset mocks. However, it's better to change the design of your tests. You should have two separate tests, one for each case, and you should create fresh mocks before each test.
Something like this:
#Before
public void setup() {
// create a myService mock
}
#Test
public void testMyFacadeMethodWithDataChange() {
// change data, call tested method
verify(myService).callServiceMethod();
}
#Test
public void testMyFacadeMethodWithoutDataChange() {
// no data change, call tested method
verify(myService, times(0)).callServiceMethod();
}
Yes, Mockito does not automatically reset the number of method invocations.
You can use Mockito.reset(T) to reset your mock.
However, you should try to avoid to use that method. It is usually not necessary if the test code is smart and consequently its presence might indicate a code smell. See
http://docs.mockito.googlecode.com/hg/org/mockito/Mockito.html#17

Using mocked method argument to mock next steps

I have a method in my code that looks something like this:
action.onResult(new Handler<MyClass>() {
#Override
public MyClass handle() { // Do something here }
}
}
I want to be able to mock it (using Mockito). Something like this:
when(mockedAction.onResult(any(Handler.class))).thenReturn(firstArg.handle());
Meaning, I want to call the handle method of the argument that's sent to the method onResult. I can't mock the handler because it uses inner methods of the calling class (I thought about using a private class but haven't reached a good enough solution)
Motivation: This is an asynchronous callback mechanism that's used in a synchronous area. I want to mock the call to the handler itself in order to continue the flow synchronously in the code.
OK, UNTESTED but here is a possible use of ArgumentCaptor for this scenario:
final ArgumentCaptor<Handler> captor = ArgumentCaptor.forClass(Handler.class);
when(mock.onResult(captor.capture())).thenReturn(captor.getValue().handle());
Not sure however whether the captor has the "time" to initialize here.

Resources