Unable to create a Spy on a constructor in Spock - unit-testing

The declaration I'm looking to create a spy on:
Producer<String, String> producer = new KafkaProducer<String, String>(producerProps)
My attempts to create the spy failed:
def spySvc = GroovySpy(service, global:true)
2 * new service.createKafkaProducer() >> mockedProducer; // fail
2 * new KafkaProducer(_) >> mockedProducer; // fail
2 * new KafkaProducer<String,String>(_) >> mockedProducer; //fail
But when I factor out the Producer creation into its own method createKafkaProducer() and create a spy on the method invocation like so , it works:
2 * service.createKafkaProducer() >> mockedProducer; // success
Any ideas?
( I realize that the code should be refactored to use proper DI, then the problem is trivial and doesn't need a Spy )

I think #rafaelim is correct , KafkaProducer is a statically compiled code and GroovySpies don't work on it .

Related

How to create a ReplaySubject with RxCpp?

In my c++ project, I need to create Subjects having an initial value, that may be updated. On each subscription/update, subscribers may trigger then data processing... In a previous Angular (RxJS) project, this kind of behavior was handled with ReplaySubject(1).
I'm not able to reproduce this using c++ rxcpp lib.
I've looked up for documentation, snippets, tutorials, but without success.
Expected pseudocode (typescript):
private dataSub: ReplaySubject<Data> = new ReplaySubject<Data>(1);
private init = false;
// public Observable, immediatly share last published value
get currentData$(): Observable<Data> {
if (!this.init) {
return this.initData().pipe(switchMap(
() => this.dataSub.asObservable()
));
}
return this.dataSub.asObservable();
}
I think you are looking for rxcpp::subjects::replay.
Please try this:
auto coordination = rxcpp::observe_on_new_thread();
rxcpp::subjects::replay<int, decltype(coordination)> test(1, coordination);
// to emit data
test.get_observer().on_next(1);
test.get_observer().on_next(2);
test.get_observer().on_next(3);
// to subscribe
test.get_observable().subscribe([](auto && v)
printf("%d\n", v); // this will print '3'
});

Unit testing a GORM call with a closure

I have a Grails service that does a where query like this:
List<Car> search(Long makeId = null) {
Car.where {
join("make")
if(makeId) {
make.id == makeId
}
}.findAll()
}
I'm trying to unit test it with Spock like this:
def setup() {
GroovyMock(Car, global: true)
}
void "test search"() {
when:
service.search()
then:
1 * Car.where {}
}
However, I can't seem to find a way to test the content of the closure.
I can get the test to pass by verifying 1 * Car.where(_), but how can I make assertions on the content of the closure, i.e. that join was called and that the make.id constraint is specified only when needed?
You could set the closure's delegate to be an Mock of DetachedCriteria to make assertions on it. DetachedCriteria is the main class used in gorm to build the query.
Example:
given: 'Mocking DetachedCriteria'
DetachedCriteria detachedCriteriaMock = Mock(DetachedCriteria)
and: 'Just to avoid nullPointerException when findAll() call happens on service'
1 * detachedCriteriaMock.iterator() >> [].listIterator()
when:
service.search(1L)
then:
// Capture the argument
1 * Car.where(_) >> { args ->
args[0].delegate = detachedCriteriaMock
args[0].call()
return detachedCriteriaMock
}
// Join is a method on detached criteria
1 * detachedCriteriaMock.join('make')
// Make is an association, so detachedCriteria uses the methodMissing to find the property.
// In this case, we call the closure setting the delegate to the mock
1 * detachedCriteriaMock.methodMissing('make', _) >> { args ->
// args[1] is the list of arguments.
// args[1][0] is the closure itself passed to detachedCriteria
args[1][0].delegate = detachedCriteriaMock
args[1][0].call()
}
// If id is passed, it must compare (eq method) with value 1
1 * detachedCriteriaMock.eq('id', 1L)

How to mock multiple methods of same class in grails using spock?

I have a unit test in which I want to mock two methods of a service. I know how to do it once :
def caseHistoryMock = mockFor(CaseHistoryService)
caseHistoryMock.demand.getLatestCaseHistory(1..1) {String caseNumber, String productFamily -> return caseHistoryObj }
controller.caseHistoryService = caseHistoryMock.createMock()
How do I mock another method of caseHistoryService. The calls to methods in my controller are as follows :
def caseHistoryObj = caseHistoryService.getLatestCaseHistory(alert.caseNumber, alert.productFamily)
and
caseHistoryService.saveCaseHistory(caseHistoryMap)
*I am using grails 2.5.1.
Thanks in advance,
Apoorv
You can mock it with Mock function:
def caseHistoryMock = Mock(CaseHistoryService)
1 * caseHistoryMock.getLatestCaseHistory(_, _) >> caseHistoryObj
1 * caseHistoryMock.saveCaseHistory(_)
controller.caseHistoryService = caseHistoryMock
The 1 * is optional and describs how often the function should be called.

Using decision within a java delegate

I am trying to evaluate a decision inside a camunda java delegate that I created. Following is the code that I am using. Upon executing the delegate( which runs fine without the DMN part), I get an error stating:
java.lang.NoClassDefFoundError: de/odysseus/el/util/SimpleContext"
I am using gradle and have added the following to my .build :
compile 'org.camunda.bpm.dmn:camunda-engine-dmn' ,
'org.camunda.bpm.dmn:camunda-engine-feel-juel:7.5.0-alpha2' ,
'de.odysseus.juel:juel-spi:2.2.7',
'de.odysseus.juel:juel-api:2.2.7' ,
'de.odysseus.juel:juel-impl:2.2.7'
Any suggestion how can I fix this error up? Thanks.
DMN Code:
DmnEngine dmnEngine = DmnEngineConfiguration.createDefaultDmnEngineConfiguration().buildEngine();
// read the DMN XML file as input stream
InputStream inputStream = CheckDatafileExistsExecutor.class.getResourceAsStream("decision1.xml");
// parse the DMN decision from the input stream
DmnDecision decision = dmnEngine.parseDecision("Decision_13nychf", inputStream);
//accessing the input variables
VariableMap variables = Variables.fromMap((Map<String, Object>) decision);
// evaluate the decision table with the input variables
DmnDecisionTableResult result = dmnEngine.evaluateDecisionTable(decision, variables);
int size = result.size();
DmnDecisionRuleResult ruleResult = result.get(0);
Remove all your dependencies and add only compile group: 'org.camunda.bpm.dmn', name: 'camunda-engine-dmn', version: '7.6.0'
You can try also menskis example, but change the camunda-engine-dmn to 7.6.0
and
DmnDecisionTableResult results = dmnEngine.evaluateDecisionTable("decision", "Example.dmn", variables);
to
InputStream fileAsStream = IoUtil.fileAsStream("Example.dmn");
DmnDecisionTableResult results = dmnEngine.evaluateDecisionTable("decision", fileAsStream, variables);
You can use delegate service for decision evaluation based on key or Id,
eg:-
public void execute(DelegateExecution delegateExecution) throws Exception{
DecisionService decisionService = delegateExecution.getProcessEngineServices().getDecisionService();
decisionService.evaluateDecisionByKey(dmnToInvoke).variables(delegateExecution.get Variables()).evaluate();
}

Spock Testing and mocking or stubing database interaction

I have a private controller method that is used by multiple actions to retrieve an object from the database. I can not for the life of me correctly mock/stub the call to the database. The Controller method is:
private Order getSalesOrder(){
def order = Order.get(params.id)
if(!order){
flash.message = (code: 'default.not.found.message', args: [message(code: 'order.label', default: 'Order'), params.id])
redirect action: "list"
return
}
return order
}
The Test method I have at this point is:
def "test getSalesOrder returns Sales Order"(){
given:
params.id >> 3002L
criteriaSetup()
Order testOrder = salesOrders[2]
Order.metaClass.static.get() >> testOrder
when:
def order = controller.getSalesOrder()
then:
1 * Order.get(3002) >> testOrder
//1 * Order.get() >> salesOrders[2]
order == testOrder
}
My results are either a message about too few invocations or I just get a null value back. Both of which cause the test to fail.
I have tried variations of this by using examples found from various blogs or tutorials such as:
Order.metaClass.static.get() >> testOrder
Order.metaClass.methods.get = { return testOrder }
1 * Order.get(3002) >> testOrder
1 * Order.get(params.id) >> testOrder
I'm not sure where to go from here, since I'm new to spock tests, Mocking and Stubing in general. And due to the fact that we are writing test for legacy code it is even more confusing.
You could simply use #Mock([Order]) on top of your test class declaration
I think your failure case of too few invocations is the correct one. I don't think you can check 1 * Order.get(3002). This call will always return 0 invocations, and you would be checking for 1.
You would either have to mock this method with a counter in it to do the count check.