Tech ramblings by Marcin

Inteligentny mock w SoapUI

2009-11-18 22:20

Któż z nas nie testował WebService'ów, a któż z nas nie używał do tego SoapUI :) Ok, z rzeczami oczywistymi dyskutować nie będę, ale przy okazji jednego projekciku okazało się, że fajnie by było gdyby mój mock potrafił zrobić coś więcej niż tylko odpowiedzieć na nadesłany komunikat.

Oczywiście sam SoapUI posiada dosyć spory wachlarz możliwości, bo może wysłać losowy request spośród wprowadzonych, lub wysyłać wedle sekwencji, itp.

Problem w tym, że moim wysublimowanym życzeniem było aby korelować komunikaty określonego typu na podstawie jednego pola z XMLa - nazwijmy je polem "X". Jeśli w polu X przyszła wartość, której do tej pory nie widzieliśmy - odpowiedz jednym komunikatem, jeśli ta wartość już została przez nas odebrana (ostatnio :) ), to prześlij trochę inną odpowiedź.

Na pomoc przyszedł mi wbudowany interpreter Grooviego, którym to można oskryptować kilka fragmentów aplikacji, między innymi tworzone MockService.

No cóż, rozwiązaniem mojego problemu okazało się wrzucenie poniższego skryptu do "OnRequest" konkretnego WebService'u.

import groovy.sql.Sql                                                                                                                                        
import java.sql.*;

def url = 'jdbc:oracle:thin:@localhost:1521:XE'
def driver = 'oracle.jdbc.OracleDriver'
def user = 'mnp_data' 
def password = 'mnp_data'

def sql = Sql.newInstance(url, user, password, driver)

def groovyUtils = new com.eviware.soapui.support.GroovyUtils(context)

def holder = groovyUtils.getXmlHolder( mockRequest.requestContent)

holder.declareNamespace("xxx", "http://www.ftang.com/example")

def props = mockRunner.mockService
context.put('props', props);

def _phoneNumber = holder.getNodeValue( "//xxx:number")
log.error(_phoneNumber)

if (_phoneNumber != null) {
    if (context.phoneNumber != _phoneNumber) {
        context.setProperty('phoneNumber', _phoneNumber)
        context.setProperty('responseType', 0)
    } else {
        context.setProperty('responseType', 1)
    }   
    sql.eachRow("select * from cases where phone_number = ?", [_phoneNumber]) { 
            log.error(it)
            context.setProperty("caseId", it['case_id'])
        }  
}

def _getPhoneNumber = { 
    return props.getPropertyValue('phoneNumber')
}
context.setProperty("getPhoneNumber", _getPhoneNumber);

def _getOpenCasesResponse = {
    if(context.get('responseType')==1)
        return "";
}

context.setProperty("getOpenCasesResponse", _getOpenCasesResponse);

Prawda, że proste? :)

A czy Wy używacie grooviego? A może SoapUI?

Comments

No popatrz, używam SoapUI :) Z groov tego korzystalismy do generowania identyfikatorow, ktore nastepnie trafialy do komunikatow.

Pozdrowienia od kolegi z akademika :)