How to rewrite removed "forEachInvocation" jmockit? - testing

I have to upgrade from jmockit v0.999.15 to jmockit v1.33 and I am having issues rewriting a test which is using "forEachInvocation"
request.addParam(anyString, anyString); minTimes = 1; maxTimes = 10;
forEachInvocation = new Object() {
void validate(String someName, String someValue) {
if(Utils.XML.equals(someName)) {
assertTrue("incorrect value",someValue.contains("This is a test"));
}
}
};
The above piece of code is part of Expectations.
In jmockit website the following is mentioned, but I am not sure how to rewrite it:
"Version 1.7: Removed the forEachInvocation field, which was deprecated in release 1.6. Existing tests using it should instead take advantage of the withCapture() and withCapture(List) methods, or convert the handler object to a Delegate object assigned to the result field (in the case of a recorded expectation)."

It would be something like this:
List<String> someNames = new ArrayList<>();
List<String> someValues = new ArrayList<>();
request.addParam(withCapture(someNames), withCapture(someValues));minTimes = 1;maxTimes = 10;
for (String someName : someNames) {
// assert some name as/if needed
}
for (String someValue; someValues) {
// assert some values as/if needed
}

Related

Writing Junit by using Mockito for batch Update

Can please write the JUnit code by using Mockito for the following code :
public void writeToNoClaimLeftBehindMMF(List<NoClaimLeftMedicaidMaster> nclmm) throws Exception {
String query = Queries.NO_CLAIM_LEFT_MMF_INSERT_QUERY;
MapSqlParameterSource[] params = new MapSqlParameterSource[nclmm. Size()];
for (int i = 0; i < nclmm. Size(); i++) {
params[i] = new MapSqlParameterSource()
.addValue("envId", nclmm.get(i).getENV_ID());
mysqlJdbcTemplate.batchUpdate(query, params);
It depends on what exact behaviour of writeToNoClaimLeftBehindMMF you are trying to test. Assuming that you want to mock your mysqlJdbcTemplate instance, you will have to inject the mock as a class constructor argument and the test code would be something like this:
#Test
public void whenEmptyListIsPassed_thenWriteToNoClaimLeftBehindMMFGoesBlahBlah() {
// Given
var mockJdbcTemplate = mock(JdbcTemplate.class);
when(mockJdbcTemplate.batchUpdate(...,...)).thenReturn(whatever);
var systemUnderTest = new WhateverYourClassIsCalled(mockJdbcTemplate);
// When
systemUnderTest.writeToNoClaimLeftBehindMMF(List.of());
// Then
assertTrue(whatever you're testing);
}
See https://javadoc.io/doc/org.mockito/mockito-core/latest/index.html

Search where A or B with querydsl and spring data rest

http://localhost:8080/users?firstName=a&lastName=b ---> where firstName=a and lastName=b
How to make it to or ---> where firstName=a or lastName=b
But when I set QuerydslBinderCustomizer customize
#Override
default public void customize(QuerydslBindings bindings, QUser user) {
bindings.bind(String.class).all((StringPath path, Collection<? extends String> values) -> {
BooleanBuilder predicate = new BooleanBuilder();
values.forEach( value -> predicate.or(path.containsIgnoreCase(value) );
});
}
http://localhost:8080/users?firstName=a&firstName=b&lastName=b ---> where (firstName=a or firstName = b) and lastName=b
It seem different parameters with AND. Same parameters with what I set(predicate.or/predicate.and)
How to make it different parameters with AND like this ---> where firstName=a or firstName=b or lastName=b ??
thx.
Your current request param are grouped as List firstName and String lastName. I see that you want to keep your request parameters without a binding, but in this case it would make your life easier.
My suggestion is to make a new class with request param:
public class UserRequest {
private String lastName;
private List<String> firstName;
// getters and setters
}
For QueryDSL, you can create a builder object:
public class UserPredicateBuilder{
private List<BooleanExpression> expressions = new ArrayList<>();
public UserPredicateBuilder withFirstName(List<String> firstNameList){
QUser user = QUser.user;
expressions.add(user.firstName.in(firstNameList));
return this;
}
//.. same for other fields
public BooleanExpression build(){
if(expressions.isEmpty()){
return Expressions.asBoolean(true).isTrue();
}
BooleanExpression result = expressions.get(0);
for (int i = 1; i < expressions.size(); i++) {
result = result.and(expressions.get(i));
}
return result;
}
}
And after you can just use the builder as :
public List<User> getUsers(UserRequest userRequest){
BooleanExpression expression = new UserPredicateBuilder()
.withFirstName(userRequest.getFirstName())
// other fields
.build();
return userRepository.findAll(expression).getContent();
}
This is the recommended solution.
If you really want to keep the current params without a binding (they still need some kind of validation, otherwise it can throw an Exception in query dsl binding)
you can group them by path :
Map<StringPath,List<String>> values // example firstName => a,b
and after that to create your boolean expression based on the map:
//initial value
BooleanExpression result = Expressions.asBoolean(true).isTrue();
for (Map.Entry entry: values.entrySet()) {
result = result.and(entry.getKey().in(entry.getValues());
}
return userRepository.findAll(result);

Delete elements from a List using iterator

There is a List<Integer> tabulist that contains values [2,0,5].
Also, there is a List this.getRoutes() which contains keys [0,1,2,3,4,5].
I need to delete elements [2,0,5] from this.getRoutes().
So, as a result I must get the following entries in this.getRoutes():
[1,3,4]
Here is my code:
iter = this.getRoutes().iterator();
while(iter.hasNext())
{
Route r = iter.next();
if (tabulist.contains(r.getRouteKey()))
{
iter.remove();
}
}
The problem is that r.getRouteKey() is always 0. Therefore, I am always deleting the first elements from this.getRoutes(). I don't understand why the iterator does not move to [1,2,3,4,5].
How to solve this issue? Maybe I should also delete values from tabulist?
I didn't test my code, but here are 3 variations on the theme. You should test them in case I made a mistake, but they give an idea of the general idea.
using System;
using System.Collections;
using System.Collections.Generic;
using System.Data;
using System.Diagnostics;
public class Class1
{
public static List<int> RemoveItems1(List<int> OriginalValues, List<int> ValuesToRemove)
{
List<int> result = new List<int>();
foreach (object item_loopVariable in OriginalValues) {
item = item_loopVariable;
if ((!ValuesToRemove.Contains(item))) {
result.Add(item);
}
}
return result;
}
public static List<int> RemoveItems2(List<int> OriginalValues, List<int> ValuesToRemove)
{
List<int> result = OriginalValues;
foreach (object item_loopVariable in ValuesToRemove) {
item = item_loopVariable;
if ((OriginalValues.Contains(item))) {
result.Remove(item);
}
}
return result;
}
public static List<int> RemoveItems3(List<int> OriginalValues, List<int> ValuesToRemove)
{
List<int> result = OriginalValues;
foreach (object item_loopVariable in from item1 in ValuesToRemovewhere (OriginalValues.Contains(item1))) {
item = item_loopVariable;
result.Remove(item);
}
return result;
}
}
The first one adds only elements to get to a result. Like I said in my comment.
The second one removes elements from a result that is set to the parameter Originalvalues. The last one is basically the same as number two, but uses LINQ.
I'm using static methods because then this can be used in any situation and you don't need to instantiate a class to do this. Which adds extra unnecessary code.

How can I make my lucene search "global" (i.e. for all groups) in liferay?

I use the following in a search container to find the projects in a given group:
SearchContext searchContext = SearchContextFactory.getInstance(request);
searchContext.setStart(searchContainer.getStart());
searchContext.setKeywords(keywords);
searchContext.setEnd(searchContainer.getEnd());
results = ProjectLocalServiceUtil.getSearchedProjects(searchContext);
total = ProjectLocalServiceUtil.getSearchedProjectsCount(searchContext);
The methods getSearchedProjects translates from search results to a list of projects:
public List<Project> getSearchedProjects(SearchContext context) throws SearchException {
Indexer indexer = IndexerRegistryUtil.getIndexer(Project.class);
Hits results = indexer.search(context);
List<Project> projects = new ArrayList<Project>();
for (int i = 0; i < results.getDocs().length; i++) {
com.liferay.portal.kernel.search.Document doc = results.doc(i);
long projectId=GetterUtil.getLong(doc.get(Field.ENTRY_CLASS_PK));
Project project = null;
try {
project = ProjectLocalServiceUtil.getProject(projectId);
projects.add(project);
} catch (Exception e) {
e.printStackTrace();
continue;
}
}
return projects;
}
The results are as I expect when the search portlet is placed in the group referenced in the group I set in my projectIndexer's doGetDocument method:
document.addKeyword(Field.GROUP_ID, groupId);
document.addKeyword(Field.SCOPE_GROUP_ID, groupId);
but I would like to use the portlet to search from another group.
I tried to set the list of groupIds in the portlet, using
searchContext.setGroupIds(new long[] {projectHolder.getGroupId()});
but I still don't get any results in the search.
Any pointers on how I can search 'across groups' ?
Alain
I found the answer to my question. In order for
searchContext.setGroupIds(new long[] {group1ID, group2Id});
to have an effect the searchContext should NOT have groupId as one of its attributes.
SearchContextFactory adds GroupId in the attributes (see the extract below), so after the call to getInstance, you need to remove groupId from the attributes :
SearchContext searchContext = SearchContextFactory.getInstance(request);
Map<String, Serializable> attributes = searchContext.getAttributes();
attributes.remove("groupId");
Hope this helps someone someday.
Alain
Below, the extract from SearchContextFactory.getInstance(HttpServletRequest request) that (I believe - didn't debug it) sets the groupId attribute from the parameters :
// Extract from SearchContextFactory.java
Map<String, String[]> parameters = request.getParameterMap();
for (Map.Entry<String, String[]> entry : parameters.entrySet()) {
String name = entry.getKey();
String[] values = entry.getValue();
if ((values != null) && (values.length > 0)) {
if (values.length == 1) {
attributes.put(name, values[0]);
}
else {
attributes.put(name, values);
}
}
}
searchContext.setAttributes(attributes);

Mono.CSharp: how do I inject a value/entity *into* a script?

Just came across the latest build of Mono.CSharp and love the promise it offers.
Was able to get the following all worked out:
namespace XAct.Spikes.Duo
{
class Program
{
static void Main(string[] args)
{
CompilerSettings compilerSettings = new CompilerSettings();
compilerSettings.LoadDefaultReferences = true;
Report report = new Report(new Mono.CSharp.ConsoleReportPrinter());
Mono.CSharp.Evaluator e;
e= new Evaluator(compilerSettings, report);
//IMPORTANT:This has to be put before you include references to any assemblies
//our you;ll get a stream of errors:
e.Run("using System;");
//IMPORTANT:You have to reference the assemblies your code references...
//...including this one:
e.Run("using XAct.Spikes.Duo;");
//Go crazy -- although that takes time:
//foreach (Assembly assembly in AppDomain.CurrentDomain.GetAssemblies())
//{
// e.ReferenceAssembly(assembly);
//}
//More appropriate in most cases:
e.ReferenceAssembly((typeof(A).Assembly));
//Exception due to no semicolon
//e.Run("var a = 1+3");
//Doesn't set anything:
//e.Run("a = 1+3;");
//Works:
//e.ReferenceAssembly(typeof(A).Assembly);
e.Run("var a = 1+3;");
e.Run("A x = new A{Name=\"Joe\"};");
var a = e.Evaluate("a;");
var x = e.Evaluate("x;");
//Not extremely useful:
string check = e.GetVars();
//Note that you have to type it:
Console.WriteLine(((A) x).Name);
e = new Evaluator(compilerSettings, report);
var b = e.Evaluate("a;");
}
}
public class A
{
public string Name { get; set; }
}
}
And that was fun...can create a variable in the script's scope, and export the value.
There's just one last thing to figure out... how can I get a value in (eg, a domain entity that I want to apply a Rule script on), without using a static (am thinking of using this in a web app)?
I've seen the use compiled delegates -- but that was for the previous version of Mono.CSharp, and it doesn't seem to work any longer.
Anybody have a suggestion on how to do this with the current version?
Thanks very much.
References:
* Injecting a variable into the Mono.CSharp.Evaluator (runtime compiling a LINQ query from string)
* http://naveensrinivasan.com/tag/mono/
I know it's almost 9 years later, but I think I found a viable solution to inject local variables. It is using a static variable but can still be used by multiple evaluators without collision.
You can use a static Dictionary<string, object> which holds the reference to be injected. Let's say we are doing all this from within our class CsharpConsole:
public class CsharpConsole {
public static Dictionary<string, object> InjectionRepository {get; set; } = new Dictionary<string, object>();
}
The idea is to temporarily place the value in there with a GUID as key so there won't be any conflict between multiple evaluator instances. To inject do this:
public void InjectLocal(string name, object value, string type=null) {
var id = Guid.NewGuid().ToString();
InjectionRepository[id] = value;
type = type ?? value.GetType().FullName;
// note for generic or nested types value.GetType().FullName won't return a compilable type string, so you have to set the type parameter manually
var success = _evaluator.Run($"var {name} = ({type})MyNamespace.CsharpConsole.InjectionRepository[\"{id}\"];");
// clean it up to avoid memory leak
InjectionRepository.Remove(id);
}
Also for accessing local variables there is a workaround using Reflection so you can have a nice [] accessor with get and set:
public object this[string variable]
{
get
{
FieldInfo fieldInfo = typeof(Evaluator).GetField("fields", BindingFlags.NonPublic | BindingFlags.Instance);
if (fieldInfo != null)
{
var fields = fieldInfo.GetValue(_evaluator) as Dictionary<string, Tuple<FieldSpec, FieldInfo>>;
if (fields != null)
{
if (fields.TryGetValue(variable, out var tuple) && tuple != null)
{
var value = tuple.Item2.GetValue(_evaluator);
return value;
}
}
}
return null;
}
set
{
InjectLocal(variable, value);
}
}
Using this trick, you can even inject delegates and functions that your evaluated code can call from within the script. For instance, I inject a print function which my code can call to ouput something to the gui console window:
public delegate void PrintFunc(params object[] o);
public void puts(params object[] o)
{
// call the OnPrint event to redirect the output to gui console
if (OnPrint!=null)
OnPrint(string.Join("", o.Select(x => (x ?? "null").ToString() + "\n").ToArray()));
}
This puts function can now be easily injected like this:
InjectLocal("puts", (PrintFunc)puts, "CsInterpreter2.PrintFunc");
And just be called from within your scripts:
puts(new object[] { "hello", "world!" });
Note, there is also a native function print but it directly writes to STDOUT and redirecting individual output from multiple console windows is not possible.