GWTTest java.lang.NullPointerException cannot invoke because "this.service" is null - java

I've a problem with GWT unit test, this is the code
StudenteServiceAsync service;
public void gwtSetUp(){
// Create the service that we will test.
service = GWT.create(StudenteService.class);
ServiceDefTarget target = (ServiceDefTarget) service;
target.setServiceEntryPoint(GWT.getModuleBaseURL() + "progettosweng/studenti");
}
#Override
public String getModuleName() {
return "com.university";
}
#Test
public synchronized void getNumeroStudenti() throws Exception {
delayTestFinish(10000);
service.getNumeroStudenti(new AsyncCallback<Integer>() {
#Override
public void onFailure(Throwable caught) {
fail("FAIL: getNumeroStudenti");
}
#Override
public void onSuccess(Integer result) {
assertTrue(true);
}
});
}
}
when start test, it gives me an error:
java.lang.NullPointerException: Cannot invoke "com.university.client.services.StudenteServiceAsync.getNumeroStudenti(com.google.gwt.user.client.rpc.AsyncCallback)" because "this.service" is null
For me the error is never go in gwtSetUp() and the service is ever null.
what should I do? thanks

Related

Mockito - verify condition inside a method that is supposed to throw error

I have the following code that I'm trying to test:
class foo:
public void myFunction(Business business) {
...
if(someCondition) {
disconnect(business);
throw exception("message");
}
}
public void disconnect(Business business) {
...
myService.expireTokens(business);
...
}
foo test:
#Test
public void test(){
Assert.assertThrows(Exception.class, () -> {
service.myFunction(business);
verify(myService, times(1)).expireTokens(any());
});
}
So the problem above is that I can comment out the disconnect() in my if clause and the assertThrows would 'catch' the erorr / pass the test, and if the normal flow goes through, it would still throw the expected error and pass, how can I test the nested disconnect actually went through before throwing?
Move verify(myService, times(1)).expireTokens(any()) out of the Assert.assertThrows function context.
Assert.assertThrows equal next construction:
try {
//run exceptional operation
service.myFunction(business);
//code after exceptional operation will not be executed
verify(myService, times(1)).expireTokens(any());
} catch (Throwable actualThrown) {
if (expectedThrowable.isInstance(actualThrown)) {
return actualThrown;
} else {
throw new AssertionError();
}
}
So the code defined after the exceptional function will not be executed because of raised exception. This is the reason of the incorrect test behavior.
Example of the correct test implementation:
#Test
public void test() {
MyService myService = mock(MyService.class);
TestService testService = new TestService(myService);
Business business = new Business();
Assert.assertThrows(Exception.class, () -> {
testService.myFunction(business);
});
verify(myService, times(1)).expireTokens(any());
}
public class TestService {
private MyService myService;
public TestService(MyService myService) {
this.myService = myService;
}
public void myFunction(Business business) throws Exception {
if(business != null) {
disconnect(business);
throw new Exception("message");
}
}
public void disconnect(Business business) {
myService.expireTokens(business);
}
}
public class MyService {
public void expireTokens(Business business) {
}
}

Object result in Apache Camel junit test

I trying to test the camel output as Object but which fails to get exchange object.This is where it fails Customer resultCustomer = processActs.getExchanges().get(0).getIn().getBody(Customer.class). Please help me to solve this.I referred this Right way to test my object in Camel
Customer POJO:
public class Customer {
private String firstName;
private String lastName;
// getters and setters
#Override
public String toString(){
return firstName +":::" + lastName;
}
}
Test Route:
public class FileTest4 extends CamelTestSupport {
#EndpointInject(uri = "direct:teststart")
private Endpoint start;
#EndpointInject(uri = "mock:direct:processActs")
private MockEndpoint processActs;
#EndpointInject(uri = "mock:direct:write2File")
private MockEndpoint write2File;
#EndpointInject(uri = "mock:end")
private MockEndpoint mockEndResult;
#Override
public boolean isUseAdviceWith() {
return true;
}
#Override
protected RouteBuilder createRouteBuilder() throws Exception {
return new RouteBuilder() {
#Override
public void configure() throws Exception {
from("file:/var/file.log&noop=true").routeId("MY_ROUTE").to("direct:processActs");
from("direct:processActs").process(exchange -> {
List<Customer> customers = new ArrayList<>();
customers.add(new Customer("F1", "L1"));
customers.add(new Customer("F2", "L2"));
customers.add(new Customer("F3", "L3"));
exchange.getOut().setBody(customers);
}).to("direct:write2File");
from("direct:write2File").split(simple("${body}")).log("Content: ${body}");
}
};
}
#Override
protected void doPostSetup() throws Exception {
context.getRouteDefinition("MY_ROUTE").adviceWith(context, new AdviceWithRouteBuilder() {
#Override
public void configure() throws Exception {
replaceFromWith("direct:teststart");
weaveAddLast().to("mock:end");
}
});
context.start();
}
#Test
public void testUnmarshal() throws Exception {
mockEndResult.expectedMessageCount(1);
// ArrayIndex Exception here exchanges list is empty
Customer resultCustomer = processActs.getExchanges().get(0).getIn().getBody(Customer.class);
assertEquals(resultCustomer.toString(),"F1:::L1");
write2File.expectedBodiesReceived("F1:::L1", "F3:::L3", "F2:::L2");
template.sendBody("direct:teststart", new File("src/test/resources/test.txt"));
mockEndResult.assertIsSatisfied();
}
}
It looks like you're inspecting the mock endpoint before you've actually sent any exchanges. Try moving the check to the end of the test, e.g.:
#Test
public void testUnmarshal() throws Exception {
mockEndResult.expectedMessageCount(1);
write2File.expectedBodiesReceived("F1:::L1", "F3:::L3", "F2:::L2");
template.sendBody("direct:teststart", new File("src/test/resources/test.txt"));
mockEndResult.assertIsSatisfied();
Customer resultCustomer = processActs.getExchanges().get(0).getIn().getBody(Customer.class);
assertEquals(resultCustomer.toString(),"F1:::L1");
}
UPDATE
On closer inspection, I think you've got your mocks muddled up. Judging by the assertions you want to check that three customers are written out. However your mocks aren't set up for this.
mock:end is added to the end of MY_ROUTE but that will only ever see the entire customer list returned by the processor in direct:processActs
Also the mocks you declare with #EndpointInject don't get involved in the route because you don't actually mock the real endpoints. You can remove all of them apart from mockEndResult.
The following test does pass.
#Test
public void testUnmarshal() throws Exception {
mockEndResult.expectedMessageCount(1);
template.sendBody("direct:teststart", new File("src/test/resources/test.txt"));
mockEndResult.assertIsSatisfied();
#SuppressWarnings("unchecked")
List<Customer> customers = mockEndResult.getExchanges().get(0).getIn().getBody(List.class);
assertEquals(customers.get(0).toString(), "F1:::L1");
assertEquals(customers.get(1).toString(), "F2:::L2");
assertEquals(customers.get(2).toString(), "F3:::L3");
}
That might not be what you want to test, though. Instead you could weave the mock endpoint in to the splitter, then you'd be able to assert individual customers.
#Override
protected void doPostSetup() throws Exception {
context.getRouteDefinition("MY_ROUTE").adviceWith(context, new AdviceWithRouteBuilder() {
#Override
public void configure() throws Exception {
replaceFromWith("direct:teststart");
}
});
// give direct:write2File the id 'splitter' to be able to advice it
context.getRouteDefinition("splitter").adviceWith(context, new AdviceWithRouteBuilder() {
#Override
public void configure() throws Exception {
weaveByType(LogDefinition.class).after().to("mock:end");
}
});
context.start();
}
#Test
public void testUnmarshal() throws Exception {
mockEndResult.expectedMessageCount(3);
mockEndResult.expectedBodiesReceived("F1:::L1", "F2:::L2", "F3:::L3");
template.sendBody("direct:teststart", new File("src/test/resources/test.txt"));
mockEndResult.assertIsSatisfied();
}

Android testing - Robolectric + Mockito + Retrofit getting Wanted but not invoked error

Trying to use Robolectric and Mockito to test my Retrofit calls in my Android app but I am getting the following error:
Wanted but not invoked: mockApi.register(
,
);
-> at ServiceTest.testAPI(ServiceTest.java:58) Actually, there were zero interactions with this mock.
The RetroFit API call is defined in an interface as follows:
#FormUrlEncoded
#POST("/register")
void register(
#FieldMap Map<String, String> registrationParams,
Callback<JsonObject> response) ;
My test class is as follows:
#Config(constants = BuildConfig.class)
#RunWith(TestRunner.class)
public class SharedServiceTest {
private RegistrationActivity activity;
#Mock
private SharedService mockApi;
#Captor
private ArgumentCaptor<Callback<JsonObject>> cb;
#Before
public void setUp() {
MockitoAnnotations.initMocks(this);
ActivityController<RegistrationActivity> controller = Robolectric.buildActivity(RegistrationActivity.class);
activity = controller.get();
controller.create();
}
#Test
public void testAPI() throws Exception {
activity.populateFields();
activity.validateFields();
activity.register("");
Mockito.verify(mockApi).register(Mockito.anyMap(), cb.capture());
JsonObject jsonObject = new JsonObject();
jsonObject.addProperty("sessionToken", Mockito.anyString());
jsonObject.addProperty("userId", Mockito.anyString());
cb.getValue().success(jsonObject, null);
Assert.assertTrue(ShadowToast.getTextOfLatestToast().contains("Registration completed"));
}
}
The method in my RegistrationActivity that uses the API is as follows:
public void register(){
MyApplication.getInstance().getSharedService().register(mRegistrationParams, new Callback<JsonObject>() {
#Override
public void success(JsonObject jsonObject, retrofit.client.Response response) {
Toast.makeText(RegistrationActivity.this, "Registration completed", Toast.LENGTH_LONG).show();
}
#Override
public void failure(RetrofitError error) {
Toast.makeText(RegistrationActivity.this, RetrofitUtils.getErrorMessage(error), Toast.LENGTH_LONG).show();
}
});
}
The real Retrofit service comes from my own Application class which I have mocked in my test folder for robolectric to use:
public class TestMyApplication extends MyApplication
implements TestLifecycleApplication {
#Override
public void onCreate() {
super.onCreate();
}
#Override public void beforeTest(Method method) {
}
#Override public void prepareTest(Object test) {
}
#Override public void afterTest(Method method) {
}
#Override public CPSharedService getCPSharedService() {
return Mockito.mock(SharedService.class);
}
}
I have searched over the other questions on SO that have this error but none of them match what I am trying to do here or provide a solution to my issue so I am just wondering what I am doing wrong?
The mocked instance of SharedService in your TestMyApplication is not the same you declared your test class.
The Mockito.verify(mockApi).register(Mockito.anyMap(), cb.capture()); is failing because the instance referred by mockApi field is actually never called.
Another problem is that the getter in TestMyApplication always returns a new mock for each invokation:
#Override public CPSharedService getCPSharedService() {
return Mockito.mock(SharedService.class); //this creates a new "mocked" instance
}
Your scenario is not 100% clear to me, but it would be better if you could let your test set the instance of the mockApi field in your TestMyApplication instance:
public class TestMyApplication extends MyApplication
implements TestLifecycleApplication {
private SharedService sharedService;
#Override
public void onCreate() {
super.onCreate();
}
#Override public void beforeTest(Method method) {
}
#Override public void prepareTest(Object test) {
}
#Override public void afterTest(Method method) {
}
#Override public CPSharedService getCPSharedService() {
return this.sharedService;
}
public void setCPSharedService(SharedService sharedService) {
// store your mock
this.sharedService = sharedService;
}
}
and in your test class:
#Test
public void testAPI() throws Exception {
// configure you TestMyApplication
assertTrue(MyApplication.getInstance() instanceof TestMyApplication);
TestMyApplication testMyApp = (TestMyApplication) MyApplication.getInstance();
testMyApp.setCPSharedService(this.mockApi);
activity.populateFields();
activity.validateFields();
activity.register("");
Mockito.verify(this.mockApi).register(Mockito.anyMap(), cb.capture());
...
}

PowerMockito 1.6.0 verify private final overloaded methods in the Mockito Extension API

couple of days ago new version of PowerMockito has been released with support to verify private/protected method calls. Although I made it work in simple case, I am missing something with more "complicated" function. Given the following classes:
public class A {
protected void myMethod(Exception... ex) {
System.out.println("Method A");
}
protected void another() {
System.out.println("Method A 1");
}
}
:
public class B extends A {
#Override
protected void myMethod(Exception... ex) {
System.out.println("Method B");
}
#Override
protected void another() {
System.out.println("Method B 1");
}
}
:
public class C extends B {
#Override
protected void myMethod(Exception... ex) {
System.out.println("Method C");
}
public void testMe() {
myMethod(new NullPointerException("XXX"));
}
#Override
protected void another() {
System.out.println("Method C 1");
}
public void testMeAnother() {
another();
}
}
and the following test case:
#PrepareForTest({ A.class, B.class, C.class })
public class MethodTest {
#Test
public void test() throws Exception {
C classUnderTest = PowerMockito.mock(C.class);
PowerMockito.doCallRealMethod().when(classUnderTest, "testMeAnother");
PowerMockito.doCallRealMethod().when(classUnderTest, "testMe");
PowerMockito.doCallRealMethod().when(classUnderTest, "myMethod");
PowerMockito.doCallRealMethod().when(classUnderTest, "another");
classUnderTest.testMeAnother();
classUnderTest.testMe();
//this works as expected
PowerMockito.verifyPrivate(classUnderTest, times(1))
.invoke(PowerMockito.method(C.class, "another"))
.withNoArguments();
//this raises an TooManymethodsFoundException:
// Matching:
// void myMethod(...)
// void myMethod(...)
// void myMethod(...)
// three times!
PowerMockito
.verifyPrivate(classUnderTest, times(1))
.invoke(PowerMockito.method(C.class, "myMethod",
Exception[].class))
.withArguments(any(Exception[].class));
}
}
//yes, I am calling the methods on mock directly, no matter for this snippet
Full stack strace of given test can be found there
Thanks in advance!

ThreadWeaver always throws IllegalArgumentException

I am trying to use Google ThreadWeaver to write a unit test for concurrent code. No matter what I do, I will get an IllegalArgumentException. I am still working with an example, but even that does not work. This is what I tried:
public class ExampleTest {
public static class ExampleMain implements MainRunnable<Example> {
private Example example;
#Override
public Class<Example> getClassUnderTest() {
return Example.class;
}
#Override
public String getMethodName() {
return null;
}
#Override
public Method getMethod() throws NoSuchMethodException {
return null;
}
#Override
public void initialize() throws Exception {
example = new Example();
}
#Override
public Example getMainObject() {
return example;
}
#Override
public void terminate() throws Exception {
}
#Override
public void run() throws Exception {
example.test("second");
}
}
public static class ExampleSecondary implements SecondaryRunnable<Example, ExampleMain> {
private ExampleMain exampleMain;
#Override
public void initialize(ExampleMain main) throws Exception {
exampleMain = main;
}
#Override
public void terminate() throws Exception {
}
#Override
public boolean canBlock() {
return false;
}
#Override
public void run() throws Exception {
exampleMain.getMainObject().test("main");
}
}
public static class Example {
private List<String> list = new ArrayList<String>();
public String test(String s) {
System.out.println("1" + s);
list.add(s);
System.out.println("2" + s);
return list.get(0);
}
}
#Test
public void testThreadWeaver() throws Exception {
ClassInstrumentation instrumentation = Instrumentation.getClassInstrumentation(Example.class);
Method tested = Example.class.getDeclaredMethod("test", String.class);
Method breakpoint = List.class.getDeclaredMethod("add", Object.class);
CodePosition codePosition = instrumentation.afterCall(tested, breakpoint);
InterleavedRunner.interleave(new ExampleMain(), new ExampleSecondary(), Arrays.asList(codePosition)).throwExceptionsIfAny();
}
}
The stack trace says:
java.lang.IllegalArgumentException: Class Example is not instrumented
at
com.google.testing.threadtester.CallLoggerFactory.getClassInstrumentation(CallLoggerFactory.java:108)
at
com.google.testing.threadtester.Instrumentation.getClassInstrumentation(Instrumentation.java:65)
at MyTest.testThreadWeaver(MyTest.java:92
I followed the instructions at the official Google code webpage, but it does not seem to work. Any ideas?
ThreadWeaver needs to instrument your classes in order to add breakpoints to your methods. Therefore, you cannot run the tests with JUnit directly but you must run your test from a specific test runner. For your case this would be ThreadedTestRunner. The actual test methods must then be annotated with #ThreadedTest instead of #Test. This should work:
#Test
public void startTest() throws Exception {
new ThreadedTestRunner().runTests(getClass(), Example.class);
}
#ThreadedTest
public void testThreadWeaver() throws Exception {
// here comes your test
}

Categories