I am fairly new to writing mock classes.I am trying to write a test class for the below method and I am not able to proceed with mocking the method call "getSsnValue".
public void setFieldValue(String fieldValue) {
final Field<String> SSN = getSsnField(fieldValue);
if (SSN !=null) {
getSsnValue(SSN ,fieldValue);
}
}
Below is the test written for mocking the method "getSsnField" and is working fine.Can anyone help in understanding how to mock the void method "getSsnValue" so that this method will not be executed during the call "controller.setFieldValue(name);"
Code Snippet:
controller = EasyMock.createMockBuilder(Controller.class).addMockedMethod("getSsnField",String.class).createMock();
EasyMock.expect(controller.getSsnField((String)EasyMock.anyObject())).andReturn(SSN).anyTimes();
EasyMock.replay(controller);
controller.setFieldValue(name);
Are you mocking those methods because they do some heavy-lifting that you can't afford to do in your test? The reason I ask is because, IMO, if you have to create a partial mock like this in order to mock out calls to methods that live in the same class then you are probably testing at a too fine-grained level. In other words, do you really need to mock out those methods?
I also assume that, if you do want to mock those internal methods out then the only reason for the test must be to ensure that if getSsnField(fieldValue) returns a Field, that getSsnValue() is invoked with the same fieldValue.
If you want to continue down that path, here's what you need to do. In EasyMock, to mock out a void method, you don't use expect(...); Instead you just call the method directly on your mock object (before calling replay()). Doing so instructs EasyMock to create the expectation that that void method will be called.
Controller controller = EasyMock.createMockBuilder(Controller.class)
.addMockedMethod("getSsnField", String.class)//
.addMockedMethod("getSsnValue")//
.createMock();
Field<String> SSN = new Field<String>();
String name = "name";
EasyMock.expect(controller.getSsnField(name)).andReturn(SSN).anyTimes();
// Just calling the getSsnValue method on the mock sets up the expectation
// that it must be called
controller.getSsnValue(SSN, name); // Mocking void method here
EasyMock.replay(controller);
controller.setFieldValue(name);
// This step is needed in order to enforce that all mocked methods were
// actually called.
EasyMock.verify(controller);
Related
I'm trying to mock an open-source class. That class uses a number of public variables instead of get methods. I need to have the mocked class return another mocked class when that variable is accessed, but I'm not sure how. Here's an example:
SolrQueryRequest request = createNiceMock(SolrQueryRequest.class);
...
replay(request);
ResponseBuilder builder = createNiceMock(ResponseBuilder.class);
expect(builder.req).andReturn(request); // Throws exception
replay(builder);
The above example, however, throws the exception java.lang.IllegalStateException: no last call on a mock available on the builder.req line. Any idea how I can do this? Please note I don't have the option of refactoring the mocked classes.
Well, after playing around with it more I discovered it was pretty easy:
myBuilder.req = request;
Now when my class under test accesses the myBuilder.req variable, it is correctly set to my mocked SolrQueryRequest.
I'm trying to mock a call to the final method ResourceBundle.getString(). With PowerMock 1.4.12 and EasyMock 3.1, the call is not being mocked; instead, the "real" method is called.
My test class:
#RunWith(PowerMockRunner.class)
#PrepareForTest(ResourceBundle.class)
public class TestSuite {
#Before
public void setUp() throws Exception {
ResourceBundle resourceBundleMock = PowerMock.createNiceMock(ResourceBundle.class);
expect(resourceBundleMock.getString(BundleConstants.QUEUE)).andReturn("Queue");
PowerMock.replay(resourceBundleMock);
beanBeingTested.setMessages(resourceBundleMock);
}
...
}
Code in BeanBeingTested:
private ResourceBundle messages;
...
String label = messages.getString(BundleConstants.QUEUE);
Error message:
java.util.MissingResourceException: Can't find resource for bundle $java.util.ResourceBundle$$EnhancerByCGLIB$$e4a02557, key Queue
at java.util.ResourceBundle.getObject(ResourceBundle.java:384)
at java.util.ResourceBundle.getString(ResourceBundle.java:344)
at com.yoyodyne.BeanBeingTested.setUpMenus(BeanBeingTested.java:87)
When I step through the test case, the debugger shows the type of beanBeingTested.messages as "EasyMock for class java.util.ResourceBundle", so the mock is injected correctly. (Also, there's no error on the call to getString() within the expect() call during set up).
With a plain mock instead of a nice mock, I get the following error:
java.lang.AssertionError:
Unexpected method call handleGetObject("Queue"):
getString("Queue"): expected: 1, actual: 0
Any idea what I'm doing wrong?
Thanks.
You are creating an instance using EasyMock. Instead, when working with static methods, you must mock the class (using PowerMock).
It should work like that (tested with EasyMock 3.0 and PowerMock 1.5, though):
#RunWith(PowerMockRunner.class)
#PrepareForTest(ResourceBundle.class)
public class TestSuite {
#Before
public void setUp() throws Exception {
// mock the class for one method only
PowerMock.mockStaticNice(ResourceBundle.class, "getString");
// define mock-behaviour on the class, when calling the static method
expect(ResourceBundle.getString(BundleConstants.QUEUE)).andReturn("Queue");
// start the engine
PowerMock.replayAll();
}
}
(I'm aware this question is a few months old, but it might help others, though)
Try using:
#PrepareForTest({ResourceBundle.class, BeanBeingTested.class})
With only ResourceBundle in the PrepareForTest the mock will work when called directly from your unit test method, but when called from BeanBeingTested you get the real method being used.
Powermock documentation is lacking in this area.
Why bother mocking the call to the resource bundle? Generally, I try to avoid mocking the nuts and bolts of java, such as ArrayList, Date, etc. Resource bundles (and MessageFormat.format()) more or less fall into the same category for me. They generally operate on strings which are fundamentals, and if these things are broken or changing their behavior enough to break a test it's definitely something I want to know :)
Just let them grab the string (which presumably is about to be set in the UI, perhaps after . Don't bother to assert the value returned since you don't want edits to the bundle to break your test. If the string gets set on a mock UI component, This is a good place for anyObject(String.class) which correctly expresses the fact you (probably) don't actually care about the specific string displayed.
I also consider it a benefit when the test fails due to a missing message key. THAT I want to know.
I have a few static util methods in my project, some of them just pass or throw an exception. There are a lot of examples out there on how to mock a static method that has a return type other than void. But how can I mock a static method that returns void to just "doNothing()"?
The non-void version uses these lines of code:
#PrepareForTest(StaticResource.class)
...
PowerMockito.mockStatic(StaticResource.class);
...
Mockito.when(StaticResource.getResource("string")).thenReturn("string");
However if applied to a StaticResources that returns void, the compile will complain that when(T) is not applicable for void...
Any ideas?
A workaround would probably be to just have all static methods return some Boolean for success but I dislike workarounds.
You can stub a static void method like this:
PowerMockito.doNothing().when(StaticResource.class, "getResource", anyString());
Although I'm not sure why you would bother, because when you call mockStatic(StaticResource.class) all static methods in StaticResource are by default stubbed
More useful, you can capture the value passed to StaticResource.getResource() like this:
ArgumentCaptor<String> captor = ArgumentCaptor.forClass(String.class);
PowerMockito.doNothing().when(
StaticResource.class, "getResource", captor.capture());
Then you can evaluate the String that was passed to StaticResource.getResource like this:
String resourceName = captor.getValue();
Since Mockito 3.4.0, an experimental API was introduced to mock static methods.
The following example code has been tested with Mockito 4.3.1 (testImplementation("org.mockito:mockito-inline:4.3.1), and JUnit Jupiter 5.8.2, OpenJDK 11.
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.mockito.MockedStatic;
import org.mockito.Mockito;
import java.util.UUID;
public class StaticMockTest {
#Test
void showCaseStaticMock() {
try (MockedStatic<StaticMockTest> staticMock = Mockito.mockStatic(StaticMockTest.class)) {
staticMock.when(StaticMockTest::getUUIDValue).thenReturn("Mockito");
Assertions.assertEquals("Mockito", StaticMockTest.getUUIDValue());
}
// Regular UUID
UUID.fromString(StaticMockTest.getUUIDValue());
}
public static String getUUIDValue() {
return UUID.randomUUID().toString();
}
}
Previous Answer, probably Mockito 1.x/2.x with Powermock 1.x/2.x
You can do it the same way you do it with Mockito on real instances. For example you can chain stubs, the following line will make the first call do nothing, then second and future call to getResources will throw the exception :
// the stub of the static method
doNothing().doThrow(Exception.class).when(StaticResource.class);
StaticResource.getResource("string");
// the use of the mocked static code
StaticResource.getResource("string"); // do nothing
StaticResource.getResource("string"); // throw Exception
Thanks to a remark of Matt Lachman, note that if the default answer is not changed at mock creation time, the mock will do nothing by default. Hence writing the following code is equivalent to not writing it.
doNothing().doThrow(Exception.class).when(StaticResource.class);
StaticResource.getResource("string");
Though that being said, it can be interesting for colleagues that will read the test that you expect nothing for this particular code. Of course this can be adapted depending on how is perceived understandability of the test.
By the way, in my humble opinion you should avoid mocking static code if your crafting new code. At Mockito we think it's usually a hint to bad design, it might lead to poorly maintainable code. Though existing legacy code is yet another story.
Generally speaking if you need to mock private or static method, then this method does too much and should be externalized in an object that will be injected in the tested object.
Hope that helps.
Regards
In simpler terms,
Imagine if you want mock below line:
StaticClass.method();
then you write below lines of code to mock:
PowerMockito.mockStatic(StaticClass.class);
PowerMockito.doNothing().when(StaticClass.class);
StaticClass.method();
To mock a static method that return void for e.g. Fileutils.forceMKdir(File file),
Sample code:
File file =PowerMockito.mock(File.class);
PowerMockito.doNothing().when(FileUtils.class,"forceMkdir",file);
I am new to rhino mocks and unit testing in general. I am starting to write some tests for my wpf mvvm app. Here is a sample scenario I am trying to test:
The view model:
List<DataItems> _theData = new List<DataItems>();
public MyViewModel(IServer server)
{
_server = server;
InitializeData();
}
private void InitializeData()
{
_server.GetData(MyCallback);
}
private void MyCallback()
{
_theData = _server.TheData;
}
public List<DataItems> VMData
{
get
{
return _theData;
}
}
Server:
public List<DataItems> TheData
{
get
{
return _cachedData;
}
}
public void GetData(Action callBack)
{
//Populate cached data
...
if(callBack != null)
{
callBack();
}
}
In my test, I want to verify that viewModel.VMData.Count == server.TheData.Count. I tried using rhino mocks to stub the server, pre-poulating TheData with some values. The I called the view model constructor, and then tried to compare the counts.
My problem is that I do not know how to get my server to actually call back into my view model. After the vm constructor is called, InitializeData() is called as expected but the stub server's GetData call is not made.
How can I make this simple test work?
if you are stubbing IServer and expecting that the calling a method on the stub will invoke the implementation in your concrete class, that is your misconception. the GetData method on the stub instance will only return what you tell it to, and not execute any code in the concrete dependency. remember that the only thing your stub IServer object has in common with your concrete implemetation of IServer is that they both implement IServer. expecting that the side effects in the method in your concrete implemenation will happen when calling the method on the stub is just faulty.
as to how to make it work: there's not really a good way to do this test as you are stating with the design of these classes as is. you are trying to test that a side effect occurred in the dependency that you are stubbing out of participation. to really test what you want here and if you want to keep these classes with this relationship, i'd suggest that you don't mock server at all and use the real object. redesign the server so that it depends on another component that loads from the cache so you can stub that thing instead.
I have written a webmethod that returns the list of the Users althought the service works fine, when I call it from the page the methods in the webservice have return type as void.
What you might be thrown off by is that web service calls in Silverlight must be handled asynchronously.
When you define a WebMethod, say for example you have one called DoWork on a Class called WorkMan. Your code in the Silverlight would end up looking like:
WorkManSoapClient client = new WorkManSoapClient();
client.DoWorkCompleted += new EventHandler<DoWorkCompletedEventArgs>(this.DoWorkCompleteHandler); // where DoWorkCompletedHandler handles the callback.
Then you call your actual method and allow the callback to process the result.
client.DoWorkAsync();
If your webmethod returns a value, your EventArg object will have a Result property that you can leverage for the result.
One final note: a personal stylistic thing but I like lambda expressions rather than generating a whole new method for the callback. I might write something like the following:
WorkManSoapClient client = new WorkManSoapClient();
client.DoWorkCompleted += (s,e) => {
if(e.Result != null){
object foo = e.Result;
}
};
client.DoWorkAsync();