I want to mock static method of java class from Kotlin test case.
I am using below code that does not work.
It always called actual method.
mockkStatic(Aes::class)
every { Aes.decrypt(PASSWORD, SECRET_KEY) } returns PASSWORD
Actual method in java class:
public static String decrypt(String text, String secretKey) {}
The good strategy for this is to use wrapper objects around static methods if there is no other way around (for example static method belongs to 3rd party library)
class AESWrapper {
fun decrypt(String text, String secretKey) {
return Aes.decrypt(text, secretKey)
}
}
There are other solutions like PowerMock, but then you need to use PowerMockRunner as I remember which can limit you in the future
Related
I have a bunch of small support methods in Android Studio I use as shortcuts in my development process, whether it's logging or popping up a toast. Where should I put these 'misc' methods? What is best practice?
At the moment they are seperate classes e.g
public class Message {
public static void message(Context context, String message) {
Toast.makeText(context, message, Toast.LENGTH_LONG).show();
}}
Is it good to have a public 'SupportClass' filled with these methods or is this whole approach bad practice?
What I do is Create multiple helpers in a package called helpers
Something like LogHelper , StringHelper , DateHelper...
you should declare those classes final and add a private Constructor, like this
public final class StringHelper {
private StringHelper () {
//Private constructor for avoiding this class to be construct
}
//... ( your public static methods goes here )
}
Most of the developers place such methods in a class named Utils but there is neither a rule nor a convention for this.
This is not a bad practice. But if your helper class contains a lot methods, you can split up the class into other multiple classes for better maintainability.
I am coding in Haxe, Lime, OpenFl. I am trying to set up a Class to store data in a Map, referenced by class instance. The class type is to be passed in the constructor, via inference. But I am quite new to all this and can't quite figure out the syntax, this is what I got so far:
class DynamicStore<A>
{
private var hashA:Map<Class<A>,String>;
public function new<A>(paramA:Class<A>) {
hashA = new Map();
}
}
But this gives me the following error:
Abstract Map has no #:to function that accepts IMap<Class<DynamicStore.A>, String>
Is there a way to do this?
A question first:
do you really want to use classes as key? or objects?
In classes should be the key
It would be much simpler to use the classe's full name as key, like "mypackage.blob.MyClass". It's safer, easier to handle and debug.
Map<String, String>
Would suffice in that case.
If objects should be keys
Then the code would look like:
import haxe.ds.ObjectMap;
class Test<A>
{
static function main() {}
private var hashA :ObjectMap<A,String>;
public function new(paramA:A) {
hashA = new ObjectMap<A,String>();
}
}
The reason "Map" cannot be directly used in this case is that "Map" is a syntactic sugar, being resolved to StringMap, IntMap or others depending on the key type. If it doesn't know what kind of map to be used, it cannot proceed (this is mainly due to cross-compiling issues).
Remark
As a final note, I would mention your construction seems a bit wacky/strange to me. It would be interesting to know what you are trying to achieve and why you structure it the way you do.
I don't think you can use Class as the key of a Map. A good work around it to use a String as a key and the fully qualified names of the types. You can also define an abstract to move from the Type to String easily ... something like the following (code not-tested);
private var hashA : Map<String, String>;
public function addClass(className : ClassId, ...)
And the abstract will look something like this:
abstract ClassId(String) {
inline public function new(name : String) this = name;
#:from public static inline function fromClass(cls : Class<Dynamic>)
return new ClassId(Type.getClassName(cls));
#:to public inline function toClass() : Class<Dynamic>
return Type.resolveClass(this);
#:to public inline function toString() : String
return this;
}
I can see this is common practice among Android developers.
public final class TasksSample extends ListActivity {
private static final String TAG = "TasksSample";
private void method() {
Log.i(TAG, "message");
}
}
Will it be easier, if I do it this way? I need not to declare TAG for every new class.
public final class TasksSample extends ListActivity {
private void method() {
Log.i(getClass().getName(), "message");
}
}
Rather than writing getClass().getName() at each place where a log is placed in a particular activity, it is always preferred to have a TAG that would represent the name of the activity class.
Why use TAG?
When you are running your application there might be more than one Activity class in it. To distinguish which activity class has logged the information in logcat we use a TAG which of course represents the name of the class.
And the proper way (I am not saying what you have written is wrong) of writing the TAG is:
private static final String TAG = TasksSample.class.getSimpleName(); // and not "TasksSample"
Every previous answer is right, but I just wanna add a little comment.
private static final String TAG = TasksSample.class.getSimpleName();
or
private static final String TAG = "TasksSample"
The latter is used when you use proguard. As you know, proguard obfuscates class names and it affects logs too.
calling a function every time has it's toll and getClass().getName() is calling 2 functions every time you log something into the system (an already long process).
Therefor, it's better to save the tag is a final static String instead of calling the same function over and over again.
Yes its a common practice, and is supported by Google for logging & debugging. If you use getClass().getName() then you have to call getClass().getName() every time, so its a better approach use TAG.
Actually getClass().getName() returns the class name, where TAG represents easy understandable name/identification of your class.
I am creating a library project for a number of android apps.
The apps all have some common functionality that I wish to include in the library project but the library project functions require use of application specific constants
So I am looking for a way to provide the library functions with the names of the constants and allow each app to define them
An example of a specific app constant and how it is used within the library project
public class AppConstants {
public static final long APP_ID = 6;//Needs to be set for each app
}
public static long getCurrentAppId(Context context) {
return getLongPreference(context, CURRENT_APP_ID_KEY, AppConstants.APP_ID);
}
This is just one example of approximately 60 constants that need to be defined for each app for a large number of library functions
Obviously I would normally just import/include the project specific app_constants.java file but this is not possible in the library project files as it hasn't got a clue about the specific applications (rightly so)
So what is the best way to have each specific app override the constants?
Update
I took a long time deciding on which of the superb answers I have been provided with best suited my needs (Thanks everyone) In the end I chose the xml solution. I don't particularly like it because it clutters up my apps resources and I did seriously consider using the interface solution but the xml solution does work nicely
Option #1
Extend your AppConstants class in each project
Better Option#2
Use XML resources to define the constants
<?xml version="1.0" encoding="utf-8"?>
<resources>
<item type="integer" name="app_id" format="integer">6</item>
</resources>
then you can retrieve them by
Context.getResources().getInteger(R.integer.app_id);
add the xml file to your resources in each project with only the values you need different
I don't know of a great schema to do that but it would certainly work this way:
define some base class in your library
// class, enum or whatever you want it to be.
class BaseConstants {
// use some real singleton instead
public static final BaseConstants instance = new BaseConstants();
// define those values - sadly static inheritance does not work
private static final int APP_ID = 0;
private static final int CURRENT_APP_ID_KEY = 24;
// so we have to do that via methods
protected int getAppId() {
return APP_ID;
}
protected int getAppIdKey() {
return CURRENT_APP_ID_KEY;
}
}
let each Activity that wants something custom implement that
class App1Constants extends BaseConstants {
public static final App1Constants instance = new App1Constants();
private final static int APP_ID = 1;
// want a different APP_ID here.
protected int getAppId() {
return APP_ID;
}
// getAppIdKey not implemented here, uses default
}
Use that class as context to the constants for your library
class Library {
public static long getCurrentAppId(Context context, BaseConstants settings) {
return getLongPreference(context, settings.getAppIdKey(), settings.getAppId());
}
}
Activities would be like so
class myActivity extends Activity {
// each Activity can implement it's own constants class and overwrite only some values
private static final BaseConstants CONSTANTS = App1Constants.instance;
private void whatever() {
long appId = Library.getCurrentAppId(this, CONSTANTS);
}
}
class myActivity2 extends Activity {
// or could just use the default ones
private static final BaseConstants CONSTANTS = BaseConstants.instance;
private void whatever() {
long appId = Library.getCurrentAppId(this, CONSTANTS);
}
}
That schema is kind of ugly but it would work at least
Define them as enum's in your library project, like
public enum Planet { MERCURY, VENUS, MARS }
Android proper takes another approach, the dreaded constant interface, like,
interface Planets {
static final int MERCURY = 1;
static final int VENUS = 2;
...
}
However, this is a well-known Java anti-pattern (constant interface, and is covered in detail in Effective Java, I quote,
The constant interface pattern is a poor use of interfaces. That a
class uses some constants internally is an implementation detail.
Implementing a constant interface causes this implementation detail to
leak into the class’s exported API. It is of no consequence to the
users of a class that the class implements a constant interface. In
fact, it may even confuse them. Worse, it represents a commitment: if
in a future release the class is modified so that it no longer needs
to use the constants, it still must implement the interface to ensure
binary compatibility. If a nonfinal class implements a constant
interface, all of its subclasses will have their namespaces polluted
by the constants in the interface.
If you need the constants to have int values for some reason, and calling toString() on the enum isn't sufficient, you can give the enum's a extra information like,
public enum ZipCode {
LYNNWOOD(98036), SAN_JOSE(95112), ...;
private int zipCode;
private ZipCode(int zipCode) { this.zipCode = zipCode; }
public int getZipCode() { return zipCode; }
}
Note that enum's are slightly less performing than integer constants, but from a code organization and clarity perspective they are far superior.
whats the deal with
CharSequence contentTitle = R.string.value;
Error cannot convert from int to CharSequence. Is there a way around this or am i missing something?
i tried
String s = R.string.value + "";
CharSequence contentTitle = s;
it returns integers values.
Any help?
R.string.value is a call to the static field in the class R, which is auto generated by Eclipse and which does a kind of summary of all your resources. To retrieve the string, you need to use :
CharSequence contentTitle = getString(R.string.value);
If you open the R class you will see that it contains only numbers that are references to the compiled resources of your project.
To retrieve the string, you need to use getString(),
but getString() is a method from Context class.
If you want to use this method outside your Activity class, you should get link to your context first and then call:
String s = mContext.getString(R.string.somestring)
R.string.value returns the reference ID number of the resource 'value'. If you look at your R class it will appear as something like this:
public static final class string {
public static final int value=0x7f040007;
}
I've been experiencing issues with referencing the getString() method. The exact error that Eclipse spits at me is:
The method getString(int) is undefined for the type DatabaseHelper.MainDatabaseHelper
After reading for awhile I've figured out that you must reference your application's context to get access to the getString() method. I was trying to create a private SQLDatabase helper class in a content provider, however, that was not allowing me to reference the getString() method. My solution so far is to do something like this:
private class MainDatabaseHelper extends SQLiteOpenHelper {
MainDatabaseHelper(Context context) {
super(context, context.getString(R.string.createRoutesTable), null, 1);
}
public void onCreate(SQLiteDatabase db) {
db.execSQL((getContext()).getString(R.string.createRoutesTable));
}
}
Notice these two context references:
context.getString()
(getContext()).getString()
I don't know if this is the optimal long-term solution but it seems to work for the moment. Hope this helps.
You could use String s = getResources().getString(R.string.value); also.