I am trying to mock a statement which has an inline implementation. I want to test the implementation:
commonUtils.getCommandStack().execute(new RecordingCommand(commonUtils.getTed()) {
#Override
protected void doExecute() {
//Statements needs to be tested
}
});
I mocked commonUtils.getCommandStack() and commonUtils.getTed().
I tried two approaches but none of them letting the control to inside the doExecute() method.
I tried 2 approaches but none of them working for me.
Approach 1:
Mocking the inline implementation like below but did not work
`TransactionalEditingDomain mockTed = Mockito.mock(TransactionalEditingDomain.class);
Mockito.when(mockCommonUtils.getTed()).thenReturn(mockTed);
CommandStack mockCommandStack = Mockito.mock(CommandStack.class);
Mockito.when(mockTed.getCommandStack()).thenReturn(mockCommandStack);
Mockito.doNothing().when(mockCommandStack).execute(new RecordingCommand(mockTed) {
#Override
protected void doExecute() {
}
});`
Approach 2
Mocking the RecordingCommand like below but did not work
`TransactionalEditingDomain mockTed = Mockito.mock(TransactionalEditingDomain.class);
Mockito.when(mockCommonUtils.getTed()).thenReturn(mockTed);
CommandStack mockCommandStack = Mockito.mock(CommandStack.class);
Mockito.when(mockTed.getCommandStack()).thenReturn(mockCommandStack);
Command recordingCommandMock = Mockito.mock(Command.class);
Mockito.doNothing().when(mockCommandStack).execute(recordingCommandMock);`
Please help me what should I do to get the control inside doExecute() method because I have many methods like this in util.
You can write your own code to answer the mocked call. In this case, you can retrieve the object that is passed in and call it from there.
Mockito.when(mockCommandStack.execute()).thenAnswer(invocation -> {
RecordingCommand commandReceived = (RecordingCommand)invocation.getArguments[0];
commandReceived.doExecute(); // or whatever method applies here
});
Unittest verify public observable behavior (return values and/or communication with dependencies) of the unit under test.
Your inline implementation is an implementation detail which unittest expicitly do not test.
You should refactor you production code so the the inline implementation becomes a testable unit of its own.
Related
I want to mock a dependency and return a default value in most test cases since most of them should not care about the values returned but there are some certain cases like I would like to test like the dependency returns some weird values or just throw. So I am modeling it in this way. Most cases, it should return a nice and valid value.
Test Setup which return the 20L by default for all test classes.
Dependency dependency = Mockito.mock(Dependency.class);
when(dependency.returnSomeVal()).thenReturn(20L);
In a specific test cases class, I would like to override the behavior like below:
when(dependency.returnSomeVal()).thenThrow(); //failure cases
when(dependency.returnSomeVal()).thenReturn(Weird_Val); //failure cases
But I don't find a good solution to override the existing behavior? Any idea?
You can reset the mock and add behavior. In the test, do
Mockito.reset(dependency);
when(dependency.returnSomeVal()).thenThrow(); //failure cases
when(dependency.returnSomeVal()).thenReturn(Weird_Val); //failure cases
Resetting will remove all mocked behavior on this class though. If you want to remock only some methods, then you have to create the mock from scratch.
I ended using myself this pattern to mock a bunch of methods of a class providing configurations.
In a #Before method I setup a bunch of stubs for a mocked object that provide a correct configuration for each test. Afterwards, in each test it was extremely convenient to only override one of those stubs to provide a different configuration and test a different error case.
I think the response from Hari Menon is correct but it somehow defeats the purpose explained in the question. If the mock is reset, all the stubs would need to be added again, making this pattern very confusing (it would be better to not use any overriding than using reset in this case, the code would be way more straightforward).
The comments added to the question provide indeed an indirect answer on how to achieve this, and why it works, but it took me a bit to get it working.
In spite of one of the comments, I made everything work by using in my #Before fixture when().thenReturn() and overriding the concrete stub with doReturn().when()
Example:
public class WorkerTest {
private ConfigProvider mockedConfigProvider = mock(ConfigProvider.class);
#Before
public void setup() {
// Setup stubs with a correct config
when(mockedConfigProvider.getValue("property1")).thenReturn("value1");
when(mockedConfigProvider.getValue("property2")).thenReturn("value2");
when(mockedConfigProvider.getValue("property3")).thenReturn("value3");
when(mockedConfigProvider.getValue("property4")).thenReturn("value4");
}
#Test
public void test_GoodConfig(){
// The config object gets injected in the test worker
Worker testWorker = new Worker(mockedConfigProvider);
// testWorker.execute() returns true if everything went well
assertTrue(testWorker.execute());
}
#Test
public void test_BadConfigProp1(){
// Test now with a broken 'property1', overriding that stub.
doReturn(null).when(mockedConfigProvider).getValue("property1");
Worker testWorker = new Worker(mockedConfigProvider);
// testWorker.execute() returns false if there is a problem.
assertFalse(testWorker.execute());
}
#Test
public void test_BadConfigProp2(){
// This test needs to only override the result of property2
doReturn("crazy result").when(mockedConfigProvider).getValue("property2");
...
}
I have a Java class
class MyClass {
void methodA() {
//something
}
void methodB() {
//something else
}
}
I wanted to unit test methodA but methodA depends on methodB. I have gone through the spock documentation but I am not able to find how to handle this scenario. What should I do?
Note
I was not able to find an answer for this so I am self-answering this question on stackoverflow which is allowed as per stackoverlfow's self-answering policy. Added this note to avoid confusion for those who are not aware of the self-answering policy so do not remove.
It is actually documented in the spock docs, see the section partial mocks.
// this is now the object under specification, not a collaborator
def persister = Spy(MessagePersister) {
// stub a call on the same object
isPersistable(_) >> true
}
when:
persister.receive("msg")
then:
// demand a call on the same object
1 * persister.persist("msg")
This is a way without mocking where you override the needed method:
def "your spock test"() {
MyClass myClass = new MyClass() {
#Override
void methodB() {
// do something related to this test
}
}
expect:
//whatever you want to do
myClass.methodA()
}
One solution of this is to do the following in your tests
def "your spock test"() {
MyClass myClass = Mock(MyClass)
myClass.methodA() >> {
callRealMethod()
}
myClass.methodB() >> {
//your mocking logic
}
expect:
//whatever you want to do
}
callRealMethod allows you to call the actual implementation when you are mocking via spock.
I would rethink this solution a bit, because what you are doing here is you are testing mock instead of a real object. I wouldn't mock anything in this class and I would treat it as a unit for simplicity. If methodB represents different unit scope then methodA then maybe this is a good starting point for refactoring this class and extracting responsibilities encapsulated in methodB to a separate class injected to the one you are trying to test. Then mocking this injected class has much more sense in my opinion. But firstly always ask yourself why you want to mock and if there is any better alternative (mocking should be your last option worth considering).
I am working on spring based project and writing unit test case using JUnit + Mockito. I am facing a problem while stubbing boolean value to a private method of same test class (after changing access level to public, still I have failed to stub the boolean value).
Below code snippet shows the simulation of same problem
class ABC {
public String method1(User userObj){
String result = "";
if(!isValidUser(userObj.getSessionID())){
return "InvalidUser";
} else {
// execute some logic
}
return result;
}
private boolean isValidUser(String sessionId) {
// Here it calls some other class to validate the user
if (sessionId == null || UserSessionPool.getInstance().getSessionUser(sessionId) == null) {
return false;
} else {
return true;
}
}
}
Here, I would like to write a test case for method1(). In class ABC I have a method called isValidUser() which helps to identify the user with in a session by looking into a global session pool which holds all logged-in used details i.e. UserSessionPool.getInstance().getSessionUser(sessionId).
While testing method1(), the moment test controller triggers isValidUser(userObj.getSessionID()) I would like to return true from isValidUser() method, so that I can continue to test rest of the implementation logic.
So far I have tried following ways using spy and mocked object to call the isValidUser() method and try to return true but nothing worked well.
Using PowerMockito
PowerMockito.doNothing().when(spyed_ABC_ClassObject, "isValidUser", true);
or
PowerMockito.doReturn(true).when(cntrl, "isValidUser", Mockito.anyString());
Using Whitebox
Whitebox.invokeMethod(spyed_ABC_ClassObject, "isValidUser", Mockito.anyString());
Using Mockito.when
when(spyed_ABC_ClassObject.isValidUser(Mockito.anyString())).thenReturn(true);
or
Mockito.doNothing().when(spyed_ABC_ClassObject).isValidUser(Mockito.anyString());
The other answer is: fix your design instead of turning to the big PowerMock hammer.
Yes, PowerMock allows you to mock static methods. But you should understand: static is an abnormality in good OO design. You only use it when you have very good reasons. As it leads to tight coupling between your classes, and surprise: it breaks your ability to write reasonable unit tests. Yes, PowerMock works; but sometimes, it does not. When your classes grow, and you do more and more things "statically", because, you know, PowerMock will do the job ... be prepared for bizarre fails at some point, that can take hours to hunt down; without ever finding real bugs in your production code.
So, consider an alternative:
Do not use static method calls. And if there is some static method around that you can't touch; consider building a small interface around that.
Instead: use dependency injection and simply pass objects implementing some interface into your production code. Because you can mock such objects without the need for PowerMock(ito).
In that sense: you simply created hard to test code. Now you intend to fix that using PowerMock. The other way (much more reasonable in my eyes) is to learn how to write testable code in the first place. Here is a good starting point for that.
Can you please try this out.
#Before
public void setUp() {
UserSessionPool mockConnectionPool = Mockito.mock(UserSessionPool.class);
}
#Test
public void testName() throws Exception {
//given
PowerMockito.mockStatic(UserSessionPool.class);
BDDMockito.given(UserSessionPool.getInstance()(...)).willReturn(mockConnectionPool);
Mockito.when(mockConnectionPool.getSessionUser(Mockito.anylong())).thenReturn(something);
//then
PowerMockito.verifyStatic();
}
Hope this helps. Happy coding !
I am working on the Junit test case and the grading scheme is based on the coverage of the code.
I meet a problem about some #override method inside a method because it seems like I can not call that method.
Just like the example below.
public void showFollowersList(PagableResponseList<User> followers) {
m_itemList.addListener(SWT.Resize, new Listener() {
#Override
public void handleEvent(Event arg0) {
m_itemList.setLayoutData(new RowData(m_itemList.getBounds().width,
m_itemList.getBounds().height));
m_rightFrame.layout();
m_rightFrame.pack();
}
});
}
addMouseTrackListener(new MouseTrackListener() {
#Override
public void mouseHover(MouseEvent arg0) {
}
#Override
public void mouseExit(MouseEvent arg0) {
Rectangle rect = HoverClickableComposite.this.getClientArea();
if (!m_clicked && !rect.contains(arg0.x, arg0.y)) {
setBackground(m_origColor);
}
}
How can I call or cover the method like handleEvent , mouseExit and mouseHover ?
If it helps, I think someone's done a very good job at making showFollowersList un-testable. Was that deliberate?
If so, the correct answer might not actually be a set of test code, but a very low coverage score and a list of recommendations for changing the class to make it more testable...
The only way to test it at the moment would be to set things up, poke it, and check what happens.
And that would only work if you can cause a handleEvent call to be fired on your object, and certain methods were available on the class:getList, getListenerCount, etc. Then, something like:
testObject.showFollowersList(followers);
// All that method does is add listener. So check that listener got added
assertEquals(1, testObject.getList().getListenerCount());
// Now check that inner handlers behave correctly
testObject.getList().fireEvent();
// This should have created a new RowData in the list
assertNotNull(testObject.getList().getLayoutData());
But if you don't have those methods available, then it's definitely not a good idea to add them and expose the List just for the sake of Unit Testing.
Another problem is the GUI. Your Unit Tests won't have a GUI. So, your m_rightFrame will probably be null (and even if it isn't, the underlying AWT classes will be).
It is not a method 'inside a method', it is a method of an anonymous class.
Usually, with SWT or Swing programming, it is the functional (business) aspect of the code that requires much test coverage, and not the scaffolding (handlers etc.)
However, if this is what is required, there are at least two options -
Do not use anonymous inner classes for the handlers - give them names in the same package.
Use a mocking framework like Powermock with JUnit and pass mocked SWT event objects to invoke handlers so that you have coverage.
I am writing (junit) unit tests for a class which implements an exposed interface with methods like:
public Set<Setting> getUserSettings();
public Set<Setting> getOrganizationSettings();
public Set<Setting> getDefaults();
public Set<Setting> getAllSettings();
The methods for getting Settings from a specific layer do IO from various places for retrieving their results. getAllSettings() Returns a single set of all the Settings at all levels, with the 'uppermost' level having preference (i.e. if a setting exists in the default and user level, the setting in the user-level will be used.
I've already written the unit tests for getUserSettings(), getOrganizationSettings(), getDefaults(), mocking out the IO operations with Mocked objects.
The implementation for the getAllSettings() looks something like
public Set<Setting> getAllSettings(){
Set<Setting> defaults = getUserSettings();
Set<Setting> custom = getOrganizationSettings();
Set<Setting> undefined = getDefaults();
//perform some sorting and business logic
//return fully sorted set
}
My question lies in how to unit test the getAllSettings() method. Do I use mocks (using easymock/powermock) for all the downstream resource calls that the user/organization/defaultSettings methods use? It seems like there would be a cleaner/better/easier way to do it.
You could write a test in the following form
#Test
public void testGetAllSettings() {
Foo fixture = new Foo() {
public Set<Setting> getUserSettings() { // canned impl }
public Set<Setting> getOrganizationSettings() { // canned impl }
public Set<Setting> getDefaults() { // canned impl }
}
Assert.assertEquals(whatEverItShouldEqual, fixture.getAllSettings());
}
This would allow you to test the logic of get all settings, independent of the other methods.
Another alternative would be to mock the IO of these methods. If you have a layer that does the logic of IO, then that could be mocked. As you mention, this can be a pain if you have lots of dependencies. Perhaps a sign that you need less dependencies? (maybe the class should be broken up into smaller units for example?)