I found following code as example how to create post request with Volley in Java but my whole project is in Kotlin. How would equivalent Kotlin code look like?
{
#Override
protected Map<String, String> getParams()
{
Map<String, String> params = new HashMap<String, String>();
params.put("name", "Alif");
params.put("domain", "http://itsalif.info");
return params;
}
};
Link to the example code: https://www.itsalif.info/content/android-volley-tutorial-http-get-post-put
Try using this in the function you took that snippet from:
{
val params: MutableMap<String, String> = HashMap();
params.put("name", "Alif");
params.put("domain", "http://itsalif.info");
override fun getParams(): MutableMap<String, String> {
return params;
}
}
Related
Currently I am working on my flutter app using Dio package as my networking and I want to create test on the dio post (wrapped within appclient). Here my code for
app_client.dart
abstract class AppClient{
Future<Map<String, dynamic>> get(String path, {Map<String, String>? queryParameters, Map<String, String>? headers});
Future<Map<String, dynamic>> post(String path, dynamic data, {Map<String, String>? queryParameters, Map<String, String>? headers});
}
class AppClientImpl implements AppClient{
late Dio dio;
late Interceptors interceptors;
AppClientImpl({required this.dio}){
//get language code
String languageCode = StorageUtil.getSavedLanguage();
if(languageCode == "id-ID"){
languageCode = "id_ID";
}else{
languageCode = "en_US";
}
BaseOptions baseOptions = BaseOptions(
baseUrl: ServiceUrl.baseUrl,
headers: {
"Accept" : "application/json",
"Content-Type" : "application/json",
},
queryParameters: {
"language" : languageCode,
"channel" : "mobile"
}
);
dio.options = baseOptions;
interceptors = Interceptors();
interceptors.add(LogInterceptor(request: true, requestBody: true, requestHeader: true, responseBody: true, responseHeader: true));
//COMMENT BECAUSE FAILED WHEN TESTING
dio.interceptors.addAll(interceptors); // ERROR HERE!!!!
}
#override
Future<Map<String, dynamic>> get(String path, {Map<String, String>? queryParameters, Map<String, String>? headers}) async {
// return await dio.get(path, queryParameters: queryParameters);
throw UnimplementedError();
}
Future<Map<String, dynamic>> post(String path, dynamic data, {Map<String, String>? queryParameters, Map<String, String>? headers}) async{
Response response = await dio.post(path, queryParameters: queryParameters, data: Map<String, dynamic>.from(data));
if(response.statusCode == 200){
return jsonDecode(response.data);
}else{
throw Exception();
}
}
}
and here is my test class
class MockDio extends Mock implements Dio{}
void main(){
late MockDio mockDio;
late AppClientImpl appClient;
setUp((){
mockDio = MockDio();
appClient = AppClientImpl(dio: mockDio);
});
final tResponse = jsonDecode(fixture("token/token_success.json"));
final tData = {};
group("post method", (){
test(
"should return data when status code is 200",
()async{
when(
() => mockDio.post(any(), queryParameters: any(named: "queryParameters"), data: any(named: "data"))
).thenAnswer(
(invocation) async => Response(requestOptions: RequestOptions(path: "/sample"), data: fixture("token/token_success.json"), statusCode: 200)
);
final result = await appClient.post("/sample", tData);
verify(() => mockDio.post(any(), queryParameters: any(named: "queryParameters"), data: any(named: "data"))).called(1);
expect(result, tResponse);
}
);
});
}
As you can see, I inject dio instance to my appclient class and add global configuration there including interceptors.
I think everything is ok until I get these error.
Testing started at 08.54 ...
package:dio/src/dio.dart 46:20 MockDio.interceptors
package:eazyconnect/data/network/app_client/app_client.dart 44:9 new AppClientImpl
test/data/network/app_client/app_client_test.dart 23:17 main.<fn>
type 'Null' is not a subtype of type 'Interceptors'
Why this is happen? Any help and suggestion would be great!
Thanks!
You need mock interceptors too. You need pass interceptors like parameters, for class http, you can see the list interceptors have setted on Dio instance dont no in DioMock, that's why the error are happening
I am trying to read translation files eg. en.json to use with GetX localization. I tried the following code but no success. Is there any better way of doing it? Somebody suggested using auto_localize with GetX, but I'll really appreciate if I can proceed without an extra package
Map<String, Map<String, String>> get keys => {
"ar": readJson("ar"),
"en": readJson("en"),
}
I tried loading the localization information using the following function
// Fetch content from the json file
Map<String, String> readJson(String languageCode) {
Map data = {};
rootBundle
.loadString('assets/translations/$languageCode.json')
.then((response) {
data = json.decode(response);
});
return data.map((key, value) {
return MapEntry(key, value.toString());
});
}
DebugPrint() gets shows that the files were successfully loaded. However, trying to display the loaded Maps doesn't work
The readJson should be Future and because of that the empty Map returned at the end.
The way i did
create languages.json file and put all texts to it.
[
{
"name": "English",
"code": "en_US",
"texts": {
"hello": "Hello World"
}
},
{
"name": "Arabic",
"code": "ar_AE",
"texts": {
"hello": "مرحبا بالعالم"
}
}
]
implement localization class like this
class LocalizationService extends Translations {
#override
Map<String, Map<String, String>> get keys => {};
static Future<void> initLanguages() async {
final _keys = await readJson();
Get.clearTranslations();
Get.addTranslations(_keys);
}
static Future<Map<String, Map<String, String>>> readJson() async {
final res = await rootBundle.loadString('assets/languages.json');
List<dynamic> data = jsonDecode(res);
final listData = data.map((j) => I18nModel.fromJson(j)).toList();
final keys = Map<String, Map<String, String>>();
listData.forEach((value) {
final String translationKey = value.code!;
keys.addAll({translationKey: value.texts!});
});
return keys;
}
}
As you see after getting the Map data, i used Get.addTranslations(); to set language keys.
this is a GetX function to add languages on air!
create model class to parse json data
class I18nModel {
String? name;
String? code;
Map<String, String>? texts;
I18nModel(
{this.name, this.code, this.texts});
I18nModel.fromJson(Map<String, dynamic> json) {
name = json['name'];
code = json['code'];
if (json['texts'] != null) {
texts = Map<String, String>.from(json['texts']);
}
}
}
And finally call await LocalizationService.initLanguages(); before going to your first Route.
I am unable to validate a Twilio post or get request. Please find the my code piece below and help me to correct it accordingly.
public ResponseEntity<String> businessHolidays(HttpServletRequest request,#RequestParam Map<String, String> requestparams) {
Map<String,String> tempParams = new HashMap<>();
return getStringResponseEntity(request,tempParams);
}
private ResponseEntity<String> getStringResponseEntity(HttpServletRequest request, #RequestParam Map<String, String> requestparams) {
ValidateSignature(request, requestparams);
return new ResponseEntity<>("Succesful response", HttpStatus.OK);
}
public static void ValidateSignature(HttpServletRequest request, Map<String, String> ivrReuestParams) {
RequestValidator requestValidator = new RequestValidator("my authtoken");
System.out.println(request.getRequestURL().toString().replace("http", "https"));
System.out.println(requestValidator.validate(request.getRequestURL().toString().replace("http", "https"), ivrReuestParams, request.getHeader("X-Twilio-Signature")));
}
It always returns me false on the validation. Please let me know if you have any additional questions.
I am using swagger UI to test spring boot rest services But I have to pass query parameters to URL like
http://localhost:8080/v1.0/media/?user=dcisupportevg&client=20
How to pass those parameters?
Thanks in Advance.
#Bean
public Docket productApi() {
return new Docket(DocumentationType.SWAGGER_2)
.apiInfo(DEFAULT_API_INFO)
.select()
.apis(RequestHandlerSelectors
.basePackage("com.dci.rest.controller"))
.paths(regex("/.*"))
.build();
}
Controller:
#RestController
#RequestMapping({"/v1.0/media"})
public class MediaController {
#RequestMapping(value = "/" method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
public Response<Object> getAllMedia(#PathVariable Map<String, String> pathVariablesMap,HttpServletRequest request){
Response<Object> responseVO = new Response<Object>();
try {
responseVO = mediaService.getAllMedia(request,pathVariablesMap);
} catch (Exception e) {
e.printStackTrace();
}
return responseVO;
}
}
But actually, I have to use URL:http://localhost:8080/v1.0/media/?user=xxxxx&client=xxxx to get response from above method.
I am looking for some integration test examples for RabbitListenerConfigurer and RabbitListenerEndpointRegistrar and calling #rabbitListner annotation and test the message conversion and pass additional paramenters such as Channel and message properties etc.
Some thing like this
#RunWith(SpringJUnit4ClassRunner.class)
public class RabbitListenerConfigureIntegrationTests {
public final String sampleMessage="{\"ORCH_KEY\":{\"inputMap\":{},\"outputMap\":{\"activityId\":\"10001002\",\"activityStatus\":\"SUCCESS\"}}}";
#Test
public void testRabiitListenerConfigurer() throws Exception {
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(
EnableRabbitConfigWithCustomConversion.class);
RabbitListenerConfigurer registrar = ctx.getBean(RabbitListenerConfigurer.class);
/* I want to get the Listener instance here */
Message message = MessageBuilder.withBody(sampleMessage.getBytes())
.andProperties(MessagePropertiesBuilder.newInstance()
.setContentType("application/json")
.build())
.build();
/* call listener.onmessage(message) and that intern pass the call back to #rabbit listener and by that time MessageHandler which is registered should kick off and convert the message */
}
#Configuration
#EnableRabbit
public static class EnableRabbitConfigWithCustomConversion implements RabbitListenerConfigurer {
#Override
public void configureRabbitListeners(RabbitListenerEndpointRegistrar registrar) {
registrar.setMessageHandlerMethodFactory(messageHandlerMethodFactory());
}
#Bean
public ConnectionFactory mockConnectionFactory() {
return mock(ConnectionFactory.class);
}
#Bean
public SimpleRabbitListenerContainerFactory rabbitListenerContainerFactory() {
SimpleRabbitListenerContainerFactory factory = new SimpleRabbitListenerContainerFactory();
factory.setConnectionFactory(mockConnectionFactory());
factory.setAutoStartup(false);
return factory;
}
#Bean
MessageHandlerMethodFactory messageHandlerMethodFactory() {
DefaultMessageHandlerMethodFactory messageHandlerMethodFactory = new DefaultMessageHandlerMethodFactory();
messageHandlerMethodFactory.setMessageConverter(consumerJackson2MessageConverter());
return messageHandlerMethodFactory;
}
#Bean
public MappingJackson2MessageConverter consumerJackson2MessageConverter() {
return new MappingJackson2MessageConverter();
}
#Bean
public Listener messageListener1() {
return new Listener();
}
}
public class Listener {
#RabbitListener(queues = "QUEUE")
public void listen(ExchangeDTO dto, Channel chanel) {
System.out.println("Result:" + dto.getClass() + ":" + dto.toString());
/*ExchangeDTO dto = (ExchangeDTO)messageConverter.fromMessage(message);
System.out.println("dto:"+dto);*/
}
}
EDIT 2
I am not getting Exchange DTO populated with values. instead I get Null values
Here is Log :
15:00:50.994 [main] DEBUG org.springframework.amqp.rabbit.listener.adapter.MessagingMessageListenerAdapter - Processing [GenericMessage [payload=byte[93], headers={contentType=application/json, id=8bf86bf1-7e45-d136-9126-69959f92f100, timestamp=1552680050993}]]
Result:class com.dsicover.dftp.scrubber.subscriber.ExchangeDTO:DTO [inputMap={}, outputMap={}]
public class ExchangeDTO implements Serializable {
/**
*
*/
private static final long serialVersionUID = 1L;
private HashMap<String, Object> inputMap = new HashMap<String, Object>();
private HashMap<String, Object> outputMap = new HashMap<String, Object>();
public HashMap<String, Object> getInputMap() {
return inputMap;
}
public void setInputMap(HashMap<String, Object> inputMap) {
this.inputMap = inputMap;
}
public HashMap<String, Object> getOutputMap() {
return outputMap;
}
public void setOutputMap(HashMap<String, Object> outputMap) {
this.outputMap = outputMap;
}
#Override
public String toString() {
return "DTO [inputMap=" + this.inputMap + ", outputMap=" + this.outputMap + "]";
}
}
Is there any thing i am missing in Jackson2MessageConverter.
Give the #RabbitListener an id
RabbitListenerEndpointRegistry.getListenerContainer(id);
cast container to AbstractMessageListenerContainer
container.getMessageListener()
cast listener to ChannelAwareMessageListener
call onMessage().
use a mock channel and verify expected call
EDIT
#Autowired
private RabbitListenerEndpointRegistry registry;
#Test
public void test() throws Exception {
AbstractMessageListenerContainer listenerContainer =
(AbstractMessageListenerContainer) this.registry.getListenerContainer("foo");
ChannelAwareMessageListener listener =
(ChannelAwareMessageListener) listenerContainer.getMessageListener();
Channel channel = mock(Channel.class);
listener.onMessage(new Message("foo".getBytes(),
MessagePropertiesBuilder
.newInstance()
.setDeliveryTag(42L)
.build()), channel);
verify(channel).basicAck(42L, false);
}
EDIT2
Your json does not look like a DTO, it looks like a Map<String, DTO>.
This works fine for me...
#SpringBootApplication
public class So55188061Application {
public static void main(String[] args) {
SpringApplication.run(So55188061Application.class, args);
}
#RabbitListener(id = "foo", queues = "foo")
public void listen(Map<String, Foo> in, Channel channel, #Header(AmqpHeaders.DELIVERY_TAG) long tag) throws IOException {
System.out.println(in);
channel.basicAck(tag, false);
}
#Bean
public MessageConverter converter() {
return new Jackson2JsonMessageConverter();
}
public static class Foo {
private HashMap<String, Object> inputMap = new HashMap<String, Object>();
private HashMap<String, Object> outputMap = new HashMap<String, Object>();
public HashMap<String, Object> getInputMap() {
return this.inputMap;
}
public void setInputMap(HashMap<String, Object> inputMap) {
this.inputMap = inputMap;
}
public HashMap<String, Object> getOutputMap() {
return this.outputMap;
}
public void setOutputMap(HashMap<String, Object> outputMap) {
this.outputMap = outputMap;
}
#Override
public String toString() {
return "Foo [inputMap=" + this.inputMap + ", outputMap=" + this.outputMap + "]";
}
}
}
and
#RunWith(SpringRunner.class)
#SpringBootTest
public class So55188061ApplicationTests {
public final String sampleMessage =
"{\"ORCH_KEY\":{\"inputMap\":{},"
+ "\"outputMap\":{\"activityId\":\"10001002\",\"activityStatus\":\"SUCCESS\"}}}";
#Autowired
private RabbitListenerEndpointRegistry registry;
#Test
public void test() throws Exception {
AbstractMessageListenerContainer listenerContainer = (AbstractMessageListenerContainer) this.registry
.getListenerContainer("foo");
ChannelAwareMessageListener listener = (ChannelAwareMessageListener) listenerContainer.getMessageListener();
Channel channel = mock(Channel.class);
listener.onMessage(MessageBuilder.withBody(sampleMessage.getBytes())
.andProperties(MessagePropertiesBuilder.newInstance()
.setContentType("application/json")
.setDeliveryTag(42L)
.build())
.build(),
channel);
verify(channel).basicAck(42L, false);
}
}
and
{ORCH_KEY=Foo [inputMap={}, outputMap={activityId=10001002, activityStatus=SUCCESS}]}
According to your complex requirement to have everything on board, I don't see how we can make a deal with the mock(ConnectionFactory.class). We would need to mock much more to have everything working.
Instead, I would suggest to take a look into the real integration test against existing RabbitMQ or at least embedded QPid.
In addition you may consider to use a #RabbitListenerTest to spy your #RabbitListener invocation without interfering your production code.
More info is in the Reference Manual: https://docs.spring.io/spring-amqp/docs/2.1.4.RELEASE/reference/#test-harness