Forum Discussion

Unibet_Support's avatar
Unibet_Support
Contributor
13 years ago

[Res] Mockserver support for REST based projects

Hi,
I have been working very extensively on using mockserver for one of our REST based projects.And i have few questions/issue in that regard.
1)Mockserver seems to have one to one mapping between path and mockrunner.
So If you look at my example here,mockserver instance started on port 9089 has one to one association with /offering/api/v2/ub.
Lets say my path is something like /offering/api/v2/ub/restresource1.Than mockserver cant dispatch my request even if my path starts with /offering/api/v2/ub.
Thats because there is equals comparision in dispatchrequest.
So this is not at all feasible for any REST project because we usually have our resources deployed under different path though they all have start with same contextpath.
I worked my way around it by extending this MockAsWarServlet with my own one and than doing a contains match.
So i want to know if this is intentional and if it is how can we have one mockserver for every path of the REST resource?

Thanks



String pathInfo = request.getPathInfo();
if( pathInfo == null )
pathInfo = "";

for( MockRunner mockRunner : getMockRunners() )
{
[b]if( pathInfo.equals( mockRunner.getMockService().getPath() ) )[/b]
{
MockResult result = mockRunner.dispatchRequest( request, response );

if( maxResults > 0 )
{
synchronized( results )
{
while( maxResults > 0 && results.size() > maxResults )
{
results.remove( 0 );
}
if( result != null )
{
results.add( result );
}
}
}
return;
}
}


<con:mockService port="9089" path="/offering/api/v2/ub/" host="localhost"
name="MockService" bindToHostOnly="false" docroot="">
<con:settings>
<con:setting id="com.eviware.soapui.impl.wsdl.mock.WsdlMockService@require-soap-action">false</con:setting>
<con:setting id="com.eviware.soapui.impl.wsdl.mock.WsdlMockService@require-soap-version">false</con:setting>
</con:settings>
<con:startScript/>
<con:onRequestScript>import org.apache.commons.lang.StringUtils
import org.apache.commons.lang.StringUtils
import java.util.logging.Level
import java.util.logging.Logger
import org.apache.commons.io.IOUtils

def logger = Logger.getLogger( this.getClass().getName() );
def queryString = mockRequest.getHttpRequest().getQueryString()
def path = mockRequest.getHttpRequest().getPathInfo()
def testfilesdir = context.expand( '${#Project#testfilesdir}' )
def httpStatusCode = javax.servlet.http.HttpServletResponse.SC_OK

String mockServerResponseDir = "testfilesdir/mockserverresponses/"

String responseFileName = "findgroupbyid/findgroupbyid404.json";



/**Mock responses for FindALLGroups*/

if(path.matches("\\S+group\\.json")){
if(StringUtils.contains(queryString,"lang=invalid")){
responseFileName = "findallgroups/findallgroupsexception.json";
httpStatusCode = javax.servlet.http.HttpServletResponse.SC_BAD_REQUEST
}else if(StringUtils.contains(path,"group.json")){
responseFileName = "findallgroups/findallgroupshappypath.json";
}
}

/**Mock responses for FindLiveBetoffersByGroupId*/
else if(path.matches("\\S+betoffer\\/live\\/group\\/[0-9]+\\.json")){
responseFileName = "findlivebetoffersbygroupid/findlivebetoffersbygroupidhappypath.json";
if(StringUtils.contains(queryString,"lang=invalid404")){
responseFileName = "findlivebetoffersbygroupid/findlivebetoffersbygroupid404.json";
httpStatusCode = javax.servlet.http.HttpServletResponse.SC_NOT_FOUND
}else if(StringUtils.contains(queryString,"lang=invalid400")){
responseFileName = "findlivebetoffersbygroupid/findeventgroupbyid400.json";
httpStatusCode = javax.servlet.http.HttpServletResponse.SC_BAD_REQUEST
}else if(StringUtils.contains(queryString,"type=2")){
responseFileName = "findlivebetoffersbygroupid/findlivebetoffersbygroupidfilterbytype.json";
}
}


/**Mock responses for FindPrematchBetoffersByGroupId*/
else if(path.matches("\\S+betoffer\\/group\\/[0-9]+\\.json")){
responseFileName = "findprematchbetoffersbygroupid/findprematchbetoffersbygroupidhappypath.json";
if(StringUtils.contains(queryString,"lang=invalid404")){
responseFileName = "findprematchbetoffersbygroupid/findprematchbetoffersbygroupid404.json";
httpStatusCode = javax.servlet.http.HttpServletResponse.SC_NOT_FOUND
}else if(StringUtils.contains(queryString,"lang=invalid400")){
responseFileName = "findprematchbetoffersbygroupid/findeventgroupbyid400.json";
httpStatusCode = javax.servlet.http.HttpServletResponse.SC_BAD_REQUEST
}else if(StringUtils.contains(queryString,"type=2")){
responseFileName = "findprematchbetoffersbygroupid/findprematchbetoffersbygroupidfilterbytype.json";
}
}


/**Mock responses for FindEventGroupById*/
else if(path.matches("\\S+event\\/group\\/[0-9]+\\.json")){
responseFileName = "findeventgroupbyid/findeventgroupbyidhappypath.json";
if(StringUtils.contains(queryString,"lang=invalid404")){
responseFileName = "findeventgroupbyid/findeventgroupbyid404.json";
httpStatusCode = javax.servlet.http.HttpServletResponse.SC_NOT_FOUND
}else if(StringUtils.contains(queryString,"lang=invalid400")){
responseFileName = "findeventgroupbyid/findeventgroupbyid400.json";
httpStatusCode = javax.servlet.http.HttpServletResponse.SC_BAD_REQUEST
}
}


/**Mock responses for FindGroupById*/
else if(path.matches("\\S+group\\/[0-9]+\\.json")){
if(StringUtils.contains(queryString,"lang=invalid404")){
responseFileName = "findgroupbyid/findgroupbyid404.json";
httpStatusCode = javax.servlet.http.HttpServletResponse.SC_NOT_FOUND
}else if(StringUtils.contains(queryString,"lang=invalid400")){
responseFileName = "findgroupbyid/findgroupbyid400.json";
httpStatusCode = javax.servlet.http.HttpServletResponse.SC_BAD_REQUEST
}else if(StringUtils.contains(path,"/group/")){
responseFileName = "findgroupbyid/findgroupbyidhappypath.json";
}
}







def httpResponse = mockRequest.httpResponse
def fileInputStream= this.getClass().getClassLoader().getParent().getResourceAsStream(mockServerResponseDir
+ responseFileName)
httpResponse.setStatus(httpStatusCode)
def length = IOUtils.copy(fileInputStream, httpResponse.getOutputStream())
httpResponse.setContentLength( ( int )length )
httpResponse.setContentType( 'application/json' )
fileInputStream.close()

return new com.eviware.soapui.impl.wsdl.mock.WsdlMockResult(mockRequest)
</con:onRequestScript>
</con:mockService>

6 Replies

  • Hi,

    I think you will need to create just one MockService mapped to the common parent path of all your resources (ie "/offering/api/v2") and then do all processing and further dispatching in the MockServices onRequest script..

    Does that make sense?

    regards!

    /Ole
    SmartBear Software
  • Yes.That absulutely makes sense but i couldnt get that working.The onrequest script doesnt get trigerred because of this condition in the dispatchrequest method of mockaswarservlet.
    if( pathInfo.equals( mockRunner.getMockService().getPath() ) )

    So in our case,lets say path info is /offering/api/v2/ub/service1/response.json and mockRunner.getMockService().getPath() gets evaluated to /offering/api/v2/ub
    So the equality of the statement makes sure that the mockrunner cant be retrieved?
    Am i missing anything here?

    Thanks
  • Hi,

    darn - that's a bug - the standalone mockrunner uses

    if( request.getPathInfo().startsWith( root ) )
    ....

    can you use that instead for now!? I'll file a bug report...

    /Ole
    SmartBear Software
  • I cant use standalone stuff for our integration tests as it doesnt fit out process.We want to deploy this war as part of integration testing the main app and get rid of it when its done.
    Anyways i have allready overridden this mockaswarservlet and implemented that method for now.So all good now.
    Please make sure that it gets looked into.

    Thanks
  • nmrao's avatar
    nmrao
    Community Hero
    Is there something that can be shared to the community the workaround you did?