For Mocking previously we have used, Mockito with Powermock, which extensively provides all the ways to deal with different scenarios (as posted HERE ).
Few days back I came across a situation, where I need to perform Partial Mocking of a Service Class, I thought of exploring Mocking with Spock for something new, and now I can say that I am overwhelmed.
Let me brief about the scenario before going into the coding.
There is a service class, which has got a utility bean injected into it like:
Now the requirement is, we want to test the functionality of FileProcessorImpl i.e. process(), but we want to mock the behaviour of App implementation called from within the Service, so that the actual implementation do not get invoked.
Now in order to to this we came up with 2 approaches:
a) Using interfaces
b) Using Spock Mock/Spy
Using interfaces
We have written Test cases here using Spock framework:
Here is the Test class:
So, due to @ContextConfiguration the IProcessor type is injected into the Unit Test Case.
Now if we have look into the given block, we can see that we have provided an implementation of the App interface, and then we have set this reference within the injected IProcessor type.
So when we are calling processorMock.process(.... then the mocked version will get called rather than the original.
Using Spock Spy
[Please Note: The underscore (_) represents any parameter, i.e. it is wildcard representation]
So, the output will be:
Really this feature is helpful. Apart from using Spy(), you can also check out the Mock() or Stub() feature.
So till next time Keep contributing and Keep coding.
Few days back I came across a situation, where I need to perform Partial Mocking of a Service Class, I thought of exploring Mocking with Spock for something new, and now I can say that I am overwhelmed.
Let me brief about the scenario before going into the coding.
There is a service class, which has got a utility bean injected into it like:
@Service
class FileProcessorImpl implements IProcessor
{
@Autowired
App appImpl
public File process(File file) throws Exception {
// TODO Auto-generated method stub
appImpl.main(file)
appImpl.subMain(file.canonicalPath)
return file;
}
}
interface IProcessor {
File process(File file) throws Exception
}
and the Utility class is:
@Service
class AppImpl implements App
{
public void main(File args) throws Exception {
// TODO Auto-generated method stub
println " I am Implementing $args"
}
public void subMain(String args) throws Exception {
// TODO Auto-generated method stub
println " I AM A SUBMAIN METHOD IN $args "
}
}
interface App {
void main(File args) throws Exception
void subMain(String args) throws Exception
}
So, FileProcessorImpl is the service class, and App is the utility bean type injected into the service class.Now the requirement is, we want to test the functionality of FileProcessorImpl i.e. process(), but we want to mock the behaviour of App implementation called from within the Service, so that the actual implementation do not get invoked.
Now in order to to this we came up with 2 approaches:
Using interfaces
We have written Test cases here using Spock framework:
Here is the Test class:
@ContextConfiguration(classes=EIPConfig)
class EIPConfigTest extends Specification
{
@Autowired
IProcessor fileProcessorImpl
def "Test Beans"()
{
given:
def output
def file = new File("C:/Users/MIC/Desktop/web.xml")
App appMock = [ main: {println ' ****** I am being Overridden ****** '}, subMain: {println ' ****** Submain being Overridden ******'}] as App
fileProcessorImpl.appImpl = appMock
when:
output = fileProcessorImpl.process(file)
then:
output==file
}
}
The annotation @ContextConfiguration defines a normal Spring Confuguration class which contains all the Bean definitions and also does Package scanning of the beans with @ComponentScan and registers all of them in the ApplicationContext.So, due to @ContextConfiguration the IProcessor type is injected into the Unit Test Case.
Now if we have look into the given block, we can see that we have provided an implementation of the App interface, and then we have set this reference within the injected IProcessor type.
So when we are calling processorMock.process(.... then the mocked version will get called rather than the original.
Using Spock Spy
@ContextConfiguration(classes=EIPConfig)
class EIPConfigTest extends Specification
{
@Autowired
IProcessor fileProcessorImpl
def "Test Beans"()
{
given:
def output
def file = new File("C:/Users/MIC/Desktop/web.xml")
App mockApp = Spy(AppImpl)
mockApp.main(_) >> {println "****** I am being Overridden ****** '"}
//mockApp.subMain(_) >> { println ' ****** Submain being Overridden IN $it'}
fileProcessorImpl.appImpl = mockApp
when:
output = fileProcessorImpl.process(file)
then:
output==file
}
}
Now if we look into the above code snippet, then we can see that we have SPIED the Utility class i.e. AppImpl, and we have provided implementation to the main() only, while the submMain() that will be invoked will be from the Original implementation.[Please Note: The underscore (_) represents any parameter, i.e. it is wildcard representation]
So, the output will be:
****** I am being Overridden ****** ' I AM A SUBMAIN METHOD IN C:\Users\MIC\Desktop\web.xmlNow if we uncomment subMain(), then the mocked implementation will be called, i.e. we will be providing implementation of only those methods which we want to mock, otherwise not, and then in that case the original implementation will be invoked.
Really this feature is helpful. Apart from using Spy(), you can also check out the Mock() or Stub() feature.
So till next time Keep contributing and Keep coding.
No comments:
Post a Comment