I am working on azure ARM methods like provision VM and list all VM's using java sdk. I want to test my method using mockito. How can I do that without making original call to azure.
public class ListAllVM{
public static Azure azure = null;
public void listAllVM() {
azure = getAuthentication();
try {
int i = 0;
for (VirtualMachine VM : azure.virtualMachines().list()) {
System.out.println(++i +
" \n VM ID:-" + VM.id() +
" \n VM Name:-" + VM.name() +
"\n");
}
} catch (CloudException | IOException | IllegalArgumentException e) {
log.info("Listing vm failed"); }
}
}
I am facing problem while getting mock list of vm. How to mock external API class.
Your problem is: you wrote hard to test code - by using static and new. A quick suggestion how to do things differently:
public class AzureUtils {
private final Azure azure;
public AzureUtils() { this ( getAuthentication(); }
AzureUtils(Azure azure) { this.azure = azure };
public List<VM> getVms() {
return azure.virtualMachines.list();
}
In my version, you can use dependency injection to insert a mocked version of Azure.class. Now you can use any kind of mocking framework (like EasyMock or Mokito) to provide an Azure object that (again) returns mocked objects.
For the record: I am not sure where your code is getting getAuthentication() from; so unless this is a static import; something is wrong with your code in the first place.
In other words: you want to learn how to write testable code; for example by watching these videos.
On the other hand one comment says that the Azure class is final; and its constructor is private. Which is well, perfectly fair: when you design an API using final is a powerful tool to express intent.
Coming from there, you are actually pretty limited to:
as written above: you create an abstraction like AzureUtils - this way you can at least shield your own code from the effects from the design decisions by Microsoft
you enable the new experimental feature within Mockito that allows mocking final classes
you turn to PowerMock(ito) or JMockit
Related
Recently I am using play 2.4 framework for Java project.
In that I am using WsClient Library. That library is injected in my class.
#Inject WSClient wsClient
Now I am trying to write a test case for that class but test case fails because of null pointer error for wsClient variable.
wsClient.url("some url").get()
Can you please help me to resolve this?
following is the test code
// Class
public class ElasticSearch {
#Inject WSClient wsClient;
public Promise<WSResponse> createIndex() {
Logger.info("Entering ElasticSearch.createIndex()");
Logger.debug("WSClient: " + wsClient);
Promise<WSResponse> response =wsClient.url(this.getEsClient()+ "/" +this.getEsIndexName()).setContentType("application/json").put("");
Logger.info("Exiting ElasticSearch.createIndex()");
return response;
}
}
// Test function
#Test
public void testCreateIndex() {
running(fakeApplication(), new Runnable() {
public void run() {
ElasticSearch esearch= new ElasticSearch();
esearch.setEsIndexName("car_model");
assertNotNull(esearch.createIndex());
}
});
}
Before writing the options you have, I suggest to use elastic4s.
This third party lib will help you write a more functional code and give you very nice dsl to write your queries.
One more thing, I don't know what is your used case for using elasticsearch, but I recommend using a different client then the rest api, which will give you more secure connection and more efficient.
You get the NPE, because you instasiate ElasticSearch by your own with new, and don't let guice to the wiring for you, this is why the WSClient is null.
Now for your options,
You have 2 options:
Add WithApplication to your test, which will basically load your application, this will give you the access to Guice injector, from which you can take ElasticSearch class like this you have couple of ways to do it:
As described in play documentation using
import play.api.inject.guice.GuiceInjectorBuilder
import play.api.inject.bind
val injector = new GuiceInjectorBuilder()
.configure("key" -> "value")
.bindings(new ComponentModule)
.overrides(bind[Component].to[MockComponent])
.injector
val elasticsearch = injector.instanceOf[ElasticSearch]
By importing Play
import play.api.Play
val elasticsearch = Play.current.injector.instanceOf(classOf[ElasticSearch])
Using FakeApplication: just get hold of the fake application injector, and use it to get an instance of ElasticSearch class.
I don't like the above options, because you need an application running, which can make your tests very slow.
I suggest to create the WSClient by your self and instantiate ElasticSearch class with it, and run your tests.
val httpClient = NingWSClient.apply()
val elasticsearch = new ElasticSearch(httpClient)
This is a more light solution, and should make your tests run faster.
I am building an Android app. Now, I have a source code for API #1, I should get it adapted for API #2. Then I will publish the both versions for API #1 and API #2 in different packages. I can't use something like values-en, because both versions can be used worldwide. Also, the user may not have choice.
As the new version will use same UI and DB logic, (and because now the code is erroneous,) I don't want to separate the code. If i were coding in c or c++, I must use #ifdef and Makefile. However, I'm in Java. It's possible to run the API-dependent code by determining the package name in runtime, but it's somewhat weird.
I think I can use annotations. What I expect is:
package foo.app;
public class API {
public boolean prepare() { ... }
#TargetPlatform(1)
public void open() { ... }
#TargetPlatform(2)
public void open() { ... }
}
and use only one of them. Also, this is good:
package foo.app;
public class R {
#TargetPlatform(1) com.example.foo.app.R R;
#TargetPlatform(2) net.example.foo.app.R R;
}
Just defining an annotation is simple. What I don't know is, how can I exclude unused duplicates from build or execution, or so on? If the work can be done in this way, I can do anything.
You cannot use annotations for that.
It would be better to hide the implementation specific classes behind an interface.
public interface Api {
boolean prepare();
void open();
}
To create a Api instance use a factory class:
public class ApiFactory {
public static Api createApi() {
if(isTargetPlatform1())
return new com.example.foo.app.Api();
else
return new net.example.foo.app.Api();
}
private boolean isTargetPlatform1() {
// determine the current platform, e.g. by reading a configuration file
}
}
In all other places you only refer to the Api interface and ApiFactory class.
Use it like that:
Api api = ApiFactory.createApi();
api.open();
// ...
A more advanced solution would be to use dependency injection.
I've got a project that has gwt-log logging lines scattered throughout. Now I'm trying to write some unit tests and nothing seems to be working.
Any class I test that uses the gwt-log facility causes the following exception to be raised:
Caused by: com.googlecode.gwt.test.exceptions.GwtTestConfigurationException:
A custom Generator should be used to instanciate
'com.allen_sauer.gwt.log.client.LogMessageFormatter',
but gwt-test-utils does not support GWT compiler API,
so you have to add our own GwtCreateHandler with
'GwtTest.addGwtCreateHandler(..)' method or to declare your
tested object with #Mock
I have no need for the logger to function during unit tests, I'd prefer to mock it away.
I've attempted to use Mockito to mock the logger, in a few different ways... obviously I have no idea what I'm doing here, none of the following code snippets helped the situation:
public class ClockTest extends GwtTest {
#Mock private LogMessageFormatter lmf;
...
or
...
#Before
public void init() throws Exception {
LogMessageFormatter lmf = mock(LogMessageFormatter.class);
...
Any clues on how to work this out would be most appreciated!
Colin is right, you have 2 ways to deal with your error :
1) Mock the LogMessageFormatter, or at a higher level, mock your Logger instance. gwt-test-utils provides a simple API for mocking with both Mockito or EasyMock : http://code.google.com/p/gwt-test-utils/wiki/MockingClasses
2) provide your own GwtCreateHandler to instanciate the LogMessageFormatter, or at a higher your own Logger instance.
Internally, gwt-log relies on GWT's deferred binding to instanciate a LogMessageFormatter object based on your configuration, which is parsed at compile time. It use GWT's generator API to create the LogMessageFormatter class, but gwt-test-utils is not able to use those kind of Generators.
You'll have to do it "by hand", with gwt-test-utils deferred binding support : GwtCreateHandlers.
Your "LoggerGwtCreateHandler" could use JDK's InvocationHandler and Proxy classes to write a proxy for the Logger interface which would simply silent each method call, since I guess you won't care about any log call in your tests.
Here is a discussion on how to write a GwtCreateHandler : https://groups.google.com/forum/?fromgroups#!topic/gwt-test-utils-users/r_cbPsw9nIE
From the error message you posted:
you have to add our own GwtCreateHandler with
'GwtTest.addGwtCreateHandler(..)' method or to declare your
tested object with #Mock
These are the two options you have to proceed. I've only just begun to work with gwt-test-utils, but the main premise is that it doesn't run the GWT compiler or Dev Mode, so it needs other ways to handle implementing 'magic' features like GWT.create. Its method is to either require you to mock the instance (this should be a fairly common idea in most of your tests for other objects involved in testing) or to provide something like a generator, and hook it up using GwtTest.addGwtCreateHandler.
Building a mock logger shouldn't be too bad, nor should implementing GwtCreateHandler - you just need to make something that has all the log methods. If you want the logging to work, then those methods need to actually invoke some other logger, like java.util.Logger, log4j, slf4j, etc but that is not required for just getting the tests to run (but may be handy for making sure that you logging works, or finding out why your test is failing.
for those still in pain with this damn problem here is what I managed to get (With a lot of pain too ...). It'll solve the conflict between Gwt-test-utils and Gwt-log.
You're of course welcome to modify the format method ;) :
#Before
public void correctLog() {
this.addGwtCreateHandler(new GwtCreateHandler() {
#Override
public Object create(Class<?> classLiteral) throws Exception {
if (classLiteral.isAssignableFrom(LogMessageFormatter.class)) {
return new LogMessageFormatter() {
#Override
public String format(String logLevelText, String category,
String message, Throwable throwable) {
return message + " : " + throwable.getLocalizedMessage();
}
};
}
return null;
}
});
}
I am trying to accessing dll methods in java which has been written in c#. From the following code i am trying to build dll which is generated successfully.
using System;
using Microsoft.Win32;
namespace CyberoamWinHelper
{
public class RegistryAccess
{
public static String getValue(String key)
{
RegistryKey rk = Registry.CurrentUser;
RegistryKey rk1=rk.OpenSubKey("Software\\Test", RegistryKeyPermissionCheck.ReadWriteSubTree, System.Security.AccessControl.RegistryRights.FullControl);
rk1.SetValue(key, "val1");
return rk1.GetValue(key).ToString();
}
public static void createSubkey(String name)
{
RegistryKey rk = Registry.CurrentUser;
rk.CreateSubKey("Software\\Test");
}
}
}
After this i am loading the generated dll in my java program code of which is as follows
public class JNI {
/**
* #param args the command line arguments
*/
public native String getValue(String key);
public static void main(String[] args) {
// TODO code application logic here
try
{
System.loadLibrary("CyberoamWinHelper");
JNI j=new JNI();
System.out.println(j.getValue("abc"));
}
catch(UnsatisfiedLinkError e)
{
System.out.println("Ex" + e.getMessage());
}
}
}
After running this code it is giving me the following error.
"Exjni.JNI.getValue(Ljava/lang/String;)Ljava/lang/String;"
Well i am not understanding what this error is saying but i want to solve it.
And one more question i am having is since the method i am calling is a static method will it be called in this way? i mean to call static method we need
"classname.methodname"
so here will it be able to call the method?
You can only call methods via JNI if those methods were in fact designed to be called this way. Your methods absolutely are not. What you're doing here has (sorry to be so blunt) absolutely no chance of ever succeeding -- it simply doesn't work this way.
There are several ways you might proceed. One would be to learn about JNI and how to write libraries that actually work with it. Here is the canonical reference for this. Doing this with C# adds yet another layer of complexity, though.
Another way would be to give up on JNI altogether and use a more appropriate mechanism to access the methods. You can learn about JNA here; it would be entirely better suited to your goals.
Try jni4net. From their web site. Some detailed explanation is here -> How calling from Java to .NET works in jni4net
Your use of JNI is incorrect. It's difficult (although not impossible) to use JNI with C# libraries. There is an excellent tutorial on how to go about it here. Doing a C# JNI search on google shall reveal more.
You should also investigate something like Grasshopper..
EDIT
http://caffeine.berlios.de/site/documentation/quickstart.html
is a cool solution.
Helpful site for you: http://www.sahirshah.com/java/jni.html
Try:
public class myJNI {
/**
* #param args the command line arguments
*/
public static native String getValue(String key);
static
{
System.loadLibrary("CyberoamWinHelper");
}
public static void main(String[] args) {
// TODO code application logic here
try
{
String myKey = "abc";
System.out.println(getValue(myKey));
}
catch(UnsatisfiedLinkError e)
{
System.out.println("Ex" + e.getMessage());
}
}
}
You need to wrap the dll in a c++ dll as described in the above link. Just generate a header file with the "javah -jni myJNI" command and build a c++ dll with the function signature found in that header file.
Have a look at : http://www.codeproject.com/KB/cross-platform/javacsharp.aspx for a specific "hello world" example in C#
I've got some code I'm deploying to Google App Engine - Java (GAE/J) that makes use of the URLFetchService. I'd like to use JUnit to test this code. Per the testing documentation, it appears I should have a test that uses their LocalURLFetchServiceTestConfig class ROUGHLY as follows:
public class MyRemoteServiceTests {
private static final LocalURLFetchServiceTestConfig urlConfig = new LocalURLFetchServiceTestConfig();
private static final LocalServiceTestHelper helper =
new LocalServiceTestHelper(urlConfig);
#Before
public void setUp() throws Exception {
service = new SampleService();
helper.setUp();
}
#After
public void tearDown() throws Exception {
service = null;
helper.tearDown();
}
#Test
public void testThatCallsCodeThatUsesUrlFetch() {
Object data = service.getRemoteDataUsingUrlFetch("foo", "bar");
Assert.assertNotNull(data);
}
}
I'm finding that this test continues to fail despite using the "helper" as suggested in the GAE/J documentation on testing: "The API package 'urlfetch' or call 'Fetch()' was not found.".
I was assuming that using the "helper" would somehow setup the GAE environment such that when I call URLFetchServiceFactory.getURLFetchService() from within my getRemoteDataUsingUrlFetch method, the interface returned would be an instance of LocalURLFetchService that would just "work" but that seems NOT to be the case.
How can I test this code?
Am I missing something? (I'm pretty new to GAE...)
Do I have to refactor my getRemoteDataUsingUrlFetch so that it doesn't use URLFetchServiceFactory.getURLFetchService() because that makes it untestable locally??? (That sounds like it would really suck...)
Any help/suggestions much appreciated!
Actually, it turns out my problem was failure to include two additional jars that ARE mentioned on the Local Unit Testing page of the documentation. RTM FTW!
appengine-local-runtime.jar
appengine-api-stubs.jar
afaik, the LocalURLFetchService doesn't configure the GAE like you expect. It is more of a way to fetch URL from the local dev and then process the contents however. (Similarly even the LocalDatastoreService and LocalMemcacheService operate on isolated spaces within the test environment)
One way to test your code is to refactor the getRemoteDataUsingUrlFetch() to take maybe the contents of the Url response. somewhat like,
URLFetchResponse resp = LocalURLFetchService.fetch(status, request)
getRemoteDataUsingUrlFetch(foo, bar, resp)