Mockito test case not covering internal function call - java

HI i am trying to develop test cases with JUNIT + MOCKITO and facing an issue due to this ..
This is the method which i am trying to test
public Response create(Request request)
throws SQLException, InvalidSecretKeyException, UnsupportedEncodingException, GeneralSecurityException,
InvalidParametersException, InvalidAuthKeyException, ConstraintViolationExceptions, InvalidKeyHashException, InvalidApplicationKeyException {
User user = userService.validateAndReturnUserBy(request.headers("AuthKey"));
ApplicationWrapper applicationWrapper = JsonUtil.deSerialize(request.body(), ApplicationWrapper.class);
//System.out.println(applicationWrapper.getSecretKey());
Application application=new Application();
application.setKey(getApplicationKey(user.getUserName(), applicationWrapper.getType().getName(), applicationWrapper.getName()));
System.out.println("GEN KEY ::::" + getApplicationKey(user.getUserName(), applicationWrapper.getType().getName(), applicationWrapper.getName()));
application.setName(applicationWrapper.getName());
application.setPackageName(applicationWrapper.getPackageName());
application.setSendOTPInResponse(applicationWrapper.getSendOTPInResponse());
application.setType(applicationWrapper.getType());
application.setSignature(applicationWrapper.getSignature());
application.setCreatedAt(getMysqlTimeStamp());
application.setCreatedBy(user);
application.setUpdatedBy(user.getId());
application.setOtpExpiry(applicationWrapper.getOtpExpiry());
application.setOtpLength(applicationWrapper.getOtpLength());
application.setRandomNumber(tempRandomNumber);
validator.validate(application);
applicationRepository.create(application);
System.out.println(applicationWrapper);
Application thisApp =applicationRepository.getBy(application);
List<String> secretKeys = applicationWrapper.getSecretKey();
System.out.println("Application Service ::: \n"+thisApp);
insertApplicationSecretKeys(secretKeys,thisApp);
Map<String, String> responseBody = new HashMap<>();
responseBody.put("application_key", application.getKey());
responseBody.put("message", "Application created Successfully");
return new Response("success", responseBody);
}
And this is my Mockito + JUnit Test case
#Test
public void shouldCreate() throws SQLException, ResourceNotFoundException, InvalidSecretKeyException,
UnsupportedEncodingException, GeneralSecurityException, InvalidAuthKeyException, InvalidParametersException, ConstraintViolationExceptions, InvalidKeyHashException, SendGridException, InvalidApplicationKeyException {
when(request.headers("AuthKey")).thenReturn("some-auth-key");
when(userService.validateAndReturnUserBy("some-auth-key")).thenReturn(user);
when(request.body()).thenReturn(JsonUtil.toJson(make(a(ApplicationWrapperMaker.ApplicationWrapper))));
when(applicationTypeRepository.getByName("WEB")).thenReturn(make(a(ApplicationTypeMaker.ApplicationType)));
when(userRepository.getByAuthKey("some-auth-key")).thenReturn(user);
//doNothing().when(appService).insertApplicationSecretKeys(make(a(ApplicationSecretKeyMaker.ApplicationSecretKey)), make(a(Application)));
//doThrow(new RuntimeException("App created")).when(appService).insertApplicationSecretKeys(make(a(ApplicationSecretKeyMaker.ApplicationSecretKey)), make(a(Application)));
Response response = applicationService.create(request);
assertEquals("success", response.getStatus());
assertNotNull(response.getBody());
}
There is an issue where insertApplicationSecretKeys(secretKeys,thisApp);
Is being called .. As the Created application object is just a mock object this method is returning null and NullPointer exception is coming at this line.
this app variable is coming NULL.
Please help.
EDIT : HERE IS THE STACKTRACE AND OUTPUT
java.lang.NullPointerException
at com.sendotp.service.ApplicationService.insertApplicationSecretKeys(ApplicationService.java:297)
at com.sendotp.service.ApplicationService.create(ApplicationService.java:92)
at com.sendotp.service.ApplicationServiceTest.shouldCreate(ApplicationServiceTest.java:162)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
at org.junit.rules.ExpectedException$ExpectedExceptionStatement.evaluate(ExpectedException.java:239)
at org.junit.rules.RunRules.evaluate(RunRules.java:20)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.mockito.internal.runners.JUnit45AndHigherRunnerImpl.run(JUnit45AndHigherRunnerImpl.java:37)
at org.mockito.runners.MockitoJUnitRunner.run(MockitoJUnitRunner.java:62)
at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:68)
Output ::
GEN KEY ::::AhLDuwI4x34cP6-pr3WJSKoHZ7ltat13CdAcWlkZ8DHyiIk9b8-606JJ9ZPPPbTRWdnU7bPQYp4jphpdfqFoOwHs0uEc0ewE2-MHe8Yyu0XxZZQ7nw7itYVTXNFPp-a2NFP8AZ89QIznIzGstVWyO7eL7DS_qmam8BUF5XHN-VA=
ApplicationWrapper{name='someApplicationName', type=com.sendotp.model.ApplicationType#57f791c6, packageName='some.package.name', otpExpiry=86400, senderId='somesenderId', otpLength=6, requestPerIp=100, key='null', createdBy=null, updatedBy=0, createdAt=null, updatedAt=null, randomNumber='null', secretKey=[121212, 32234324], signature='some-signature,#OTP', sendOTPInResponse=0}
Application Service :::
null

Your method create is doing too much.
Especially instantiating the Application object schould be done outside the method. Object creation of other classes providing business logic should not be doen within the class using this dependency. Dependency inversion should be applied.
The simplest way is to pass the Application object as parameter to the method (which shold be renamed to configure then). In that case you could replace it by a mock on which you could verify the expected method calls.

Related

Mocking method in mockito returns a Null Pointer Exception?

I'm writing a test that calls a method from another service:
// Setup mocks
private GoalService goalService;
private Principal principal;
private Goal goal;
private SecurityService securityService;
#Before
public void setup() {
goalService = new GoalService();
principal = mock(Principal.class);
goal = mock(Goal.class);
securityService = mock(SecurityService.class, Mockito.RETURNS_DEEP_STUBS);
}
#Test
public void testRequesterOwnsGoalIsTrue() {
doReturn(1).when(securityService).getUserIdByPrincipal(principal);
when(goal.getUsersUserId()).thenReturn(1);
boolean userOwnsGoal = goalService.requesterOwnsGoal(principal, goal);
assertEquals(true, userOwnsGoal);
}
During debug, when I call securityService.getUserIdByPrincipal(principal) I get a NPE. I am not sure why. Ideally, what I want is for the method call to return 1, I don't care about testing those function internal in this unit test.
Actual Code
Boolean requesterOwnsGoal(Principal principal, Goal goal) {
Optional<Goal> optionalGoal = Optional.ofNullable(goal);
if (optionalGoal.isPresent()) {
return secService.getUserIdByPrincipal(principal) == optionalGoal.get().getUsersUserId();
}
throw new StandardUserException("Requesting user does not have access to goal");
}
Stack:
java.lang.NullPointerException
at com.habicus.core.service.Goal.GoalService.requesterOwnsGoal(GoalService.java:170)
at com.habicus.core.service.Goal.GoalServiceTest.testRequesterOwnsGoalIsTrue(GoalServiceTest.java:82)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.mockito.internal.runners.DefaultInternalRunner$1.run(DefaultInternalRunner.java:79)
at org.mockito.internal.runners.DefaultInternalRunner.run(DefaultInternalRunner.java:85)
at org.mockito.internal.runners.StrictRunner.run(StrictRunner.java:39)
at org.mockito.junit.MockitoJUnitRunner.run(MockitoJUnitRunner.java:163)
at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)
at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:47)
at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:242)
at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70)
It should be doReturn(1).when(securityService).getUserIdByPrincipal(any(principal)); to make it work.
Or
doReturn(1).when(securityService).getUserIdByPrincipal(any(Principal.class));
The code shown so far indicates that you are in fact creating a mock object. But you are not injecting that mock into your class under test!
Just creating mocks isn't sufficient. You have to ensure that they get used by the code you are testing!
Most likely that is your problem here, but as we still don't have a [mcve] we can't be sure.

Email Mocking is failing

Im trying to mock the send email functionality which sends out email when a particular job/task is completed. When i try to unit test it getting below error. Is this the right way to test it or something wrong or missing anything.
#Mock
private MailServiceImpl mailService;
#Mock
private JavaMailSenderImpl javaMailSender;
#Before
public void setUp() {
MockitoAnnotations.initMocks(this);
mailService=new MailServiceImpl(javaMailSender);
}
#Test
public void testSendEmail() {
try {
doNothing().when(mailService).sendMail(getEmailProperties());
mailService.sendMail(getEmailProperties());
verify(mailService,times(1)).sendMail(getEmailProperties());
} catch (Exception e) {
Assert.fail(e.getMessage());
}
}
public EmailProperties getEmailProperties() {
EmailProperties emailProperties = new EmailProperties();
emailProperties.setFromAddress("from#Test.com");
emailProperties.setToAddress("To#Test.com");
emailProperties.setEmailBody("Test");
emailProperties.setSubject("Test email");
emailProperties.setAttachment((File) null);
emailProperties.setMessageType(1);
return emailProperties;
}
Below is the error message is thrown from testSendEmail method. Any suggestions or any other ways to test it. google search didn't help much.
java.lang.AssertionError:
Argument passed to when() is not a mock!
Example of correct stubbing:
doThrow(new RuntimeException()).when(mock).someMethod();
at org.junit.Assert.fail(Assert.java:88)
at com.xx.xx.xx.mail.MailServiceTest.testSendEmail(MailServiceTest.java:52)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:86)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:538)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:760)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:460)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:206)
The error message is trying to say that Mockito.when() method accepts only mocked/spied objects.
You are using mailService in when method which is wrong as its neither mocked nor spied object.
mailService=new MailServiceImpl(javaMailSender);
I cannot go into too much details as the code under test is not provided.
But you can try replacing
mailService=new MailServiceImpl(javaMailSender);
with
mailService=Mockito.spy(new MailServiceImpl(javaMailSender));
This should make your mailService as something mockito will accept.
removal of doNothing().when(mailService).sendMail(getEmailProperties()); fixed the issue. Not sure what was causing this issue

ByteBuddy Agent: If intercepting methods, the JUnit test fail

I am trying to analyse JUnit tests with ByteBuddy (1.7.5) dynamically, so I don't know them in advance. I am loading them through the run() method below, and intercepting with the Agent built with the Agent() method below.
The unit tests work as expected when I run them directly in Eclipse or when I run them without installing the agent. But as soon as the Agent gets installed, the tests throw exceptions and fail.
For example: java.io.FileNotFoundException are thrown when the test creates documents (see stack trace below). I am using opensource unit tests (in this case from terrier-core, the tests in the test class org.terrier.indexing.TestSimpleXMLCollection).
Does someone know why this happens? Is it something like a race condition happening with the original test and the interceptor?
My code is the following:
public void run(#SuppressWarnings("rawtypes") Class classWithName, String testMethodName) {
interceptor.traversed = false;
Request request = Request.method(classWithName, testMethodName);
junit.run(request);
}
And:
public Agent(String pn) {
this.projectName = pn;
this.junit = new JUnitCore();
this.interceptor = new InterceptorX2();
new AgentBuilder.Default().type(
ElementMatchers.not(ElementMatchers.named("junit.framework.testcase"))
.and(ElementMatchers.nameStartsWithIgnoreCase(projectName)
.or(ElementMatchers.nameEndsWithIgnoreCase("test"))
.or(ElementMatchers.nameEndsWithIgnoreCase("tests")))
,
ElementMatchers.not(ElementMatchers.isBootstrapClassLoader()))
.transform(new AgentBuilder.Transformer() {
#Override
public Builder<?> transform(Builder<?> builder, TypeDescription arg1, ClassLoader arg2, JavaModule arg3) {
return builder
.method(
ElementMatchers.isPublic()
.and(ElementMatchers.not(ElementMatchers.isDeclaredBy(Object.class))
.and(ElementMatchers.not(ElementMatchers.isDeclaredBy(junit.framework.TestCase.class))))
).intercept(MethodDelegation.to(interceptor));
}
}).installOn(ByteBuddyAgent.install());
}
EDIT:
And my interceptor is doing nothing special:
#RuntimeType
public Object intercept(#Origin Method m, #SuperCall Callable<?> zuper, #AllArguments Object[] args, #This Object thiz) throws Exception {
return zuper.call();
}
Stacktrace of error:
java.io.FileNotFoundException: C:\Users\jackt\AppData\Local\Temp\junit6014103019704928063\terrier.properties (Das System kann die angegebene Datei nicht finden)
at java.io.FileInputStream.open0(Native Method)
at java.io.FileInputStream.open(FileInputStream.java:195)
at java.io.FileInputStream.<init>(FileInputStream.java:138)
at java.io.FileInputStream.<init>(FileInputStream.java:93)
at org.terrier.tests.ApplicationSetupBasedTest.makeEnvironment$original$m3joH5OH(ApplicationSetupBasedTest.java:81)
at org.terrier.tests.ApplicationSetupBasedTest.makeEnvironment$original$m3joH5OH$accessor$c8PeV6zd(ApplicationSetupBasedTest.java)
at org.terrier.tests.ApplicationSetupBasedTest$auxiliary$fr9IrFTX.call(Unknown Source)
at myproject.bytebuddy.introspect.InterceptorX2.intercept(InterceptorX2.java:79)
at org.terrier.tests.ApplicationSetupBasedTest.makeEnvironment(ApplicationSetupBasedTest.java)
at org.terrier.indexing.TestSimpleXMLCollection.makeEnvironment$accessor$BjbiedTZ(TestSimpleXMLCollection.java)
at org.terrier.indexing.TestSimpleXMLCollection$auxiliary$BcvkPOor.call(Unknown Source)
at myproject.bytebuddy.introspect.InterceptorX2.intercept(InterceptorX2.java:79)
at org.terrier.indexing.TestSimpleXMLCollection.makeEnvironment(TestSimpleXMLCollection.java)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:24)
at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:27)
at org.junit.rules.ExternalResource$1.evaluate(ExternalResource.java:48)
at org.junit.rules.RunRules.evaluate(RunRules.java:20)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
at org.junit.runner.JUnitCore.run(JUnitCore.java:115)
at myproject.bytebuddy.introspect.Agent.run(Agent.java:71)
at myproject.analysis.MutatorAnalysis.runAgent(MutatorAnalysis.java:43)
at myproject.Analysis.getResultsForTestCase(Analysis.java:196)
at myproject.Analysis.startPrivateAnalysis(Analysis.java:163)
at myproject.Analysis.start(Analysis.java:147)

How to call a method from a mocked interface using EasyMock

I am writing a Junit unit test for a class and I am getting a java.lang.NullPointerException on the following line :
expect(lineConfigurationHandlerMock.getDeviceControlHandler().getDeviceParameters(item1)).andReturn(myDeviceParameters);
I think (i am not sure though) that it has something to do with the method (getDeviceControlHandler) that I am calling from within the mocked interface . Because I have added this line of code before the submentioned line:
Assert.assertNotNull(comLineConfigurationHandlerMock.getDeviceControlHandler());
And I am having the following error:
java.lang.AssertionError
I am stuck here and really need some help.
Thanks in Advance.
The thrown Exception:
java.lang.NullPointerException
at de.myproject.project.classTest.testGetParameters(classTest.java:123)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:86)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:459)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:678)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192)
Here is the written test:
public class classTest {
// class under test
private classUnderTest classUnderTest;
private LineConfigurationHandler LineConfigurationHandlerMock;
private IMocksControl mocksControl;
List<DeviceParameter> myDeviceParameters;
DeviceParameter deviceParameter1;
DeviceParameter deviceParameter2;
#Before
public void setUp() throws Exception
{
mocksControl = EasyMock.createControl();
LineConfigurationHandlerMock = mocksControl.createMock(LineConfigurationHandler.class);
classUnderTest = new classUnderTest();
classUnderTest.setLineConfigurationHandler(LineConfigurationHandlerMock);
String item1 = "item1";
myDeviceParameters = new ArrayList<DeviceParameter>();
myDeviceParameters.add(deviceParameter1);
myDeviceParameters.add(deviceParameter2);
//Other stuff
}
#Test
public void testGetParameters()
{
expect(LineConfigurationHandlerMock.getDeviceControlHandler().getDeviceParameters(item1)).andReturn(myDeviceParameters);
mocksControl.replay();
//Some code .....
}
}
Here is the class under test :
public Class ClassUnderTest
{
#Inject
private LineConfigurationHandler lineConfigurationHandler;
public List<DeviceParameter> getDeviceParameters(String deviceId)
{
// Method implementation
}
#Required
public void setLineConfigurationHandler(LineConfigurationHandler lineConfigurationHandler)
{
this.lineConfigurationHandler = lineConfigurationHandler;
}
}
The interface in which the method is declared
public interface LineConfigurationHandler {
DeviceControlHandler getDeviceControlHandler();
//other Method declaration ...
}
DeviceControlHandler.class
public interface DeviceControlHandler extends Serializable{
List<DeviceParameter> getDeviceParameters(String deviceId);
//Other methods declaration ...
}
It is not simple, but very deterministic:
expect(lineConfigurationHandlerMock.getDeviceControlHandler().getDeviceParameters(item1)).andReturn(myDeviceParameters);
That line contains two items that can throw NPE:
A) lineConfigurationHandlerMock --> that object can be NULL
B) .getDeviceControlHandler() --> that method can return NULL
That's it. You can do simple printouts, like
System.out.println("mock: " + lineConfigurationHandlerMock)
System.out.println("handler: " + lineConfigurationHandlerMock.getDeviceControlHandler())
to figure which one is null. In your case, I think you are missing the setup for your lineConfigurationHandlerMock object: you have to tell it what to return when getDeviceControlHandler() is called.
In order to do that, you first have to create another mock object that should be returned when getDeviceControlHandler() is called. And that other mock, you have to configure for a call to getDeviceParameters()!
In other words: you can't specify like "mock.getA().doSomething()" - instead, you need another "mockedA" which you tell "doSomething()"; and then you tell "mock" that getA() should return "mockedA".
Update: I am not familiar with these annotations; I am used to use "EasyMock in a bare metal mode"; like
SomeObject innerMock = EasyMock.createMock(SomeObject);
expect(innerMock.doSomething()).andReturn("who cares");
SomeOther outerMock = EasyMock.createMock(SomeOther);
expect(outerMock.getDeviceControlHandler("sounds familiar")).andReturn(innerMock);

java.lang.AssertionError throwing null

We have created test for the functionality via springframework.test.context.junit4.
Below is one of the test case :
Test Class
#Test
public void testAuthorizedPut() throws Exception {
ThreadContext.bind(subject);
when(subject.isPermitted(getPlural() + ":put")).thenReturn(true);
when(subject.isPermitted(getPlural() + ":get")).thenReturn(true);
assertThat(adminTemplate().exchange(getTestHost() + "/api/1/" + getPlural() + "/45454-67567d-f5224666a9", HttpMethod.PUT, new HttpEntity<Object>(getInstance(),getStandardHeaders()),entityClass).getBody(), equalTo(getInstance()));
}
When code move to resource class that are used to mock. Like for above test code will move to PUT request of resources :
MyResource Class
#ApiOperation(value = "Update MyResource definition", notes = "Enter the id of the MyResource definition, returns updated MyResource definition", response = MyResource.class)
#Path("/{id}")
#PUT
#Timed
#Override
public MyResource update(#PathParam("id") String id, MyResource newInstance) {
return super.update(id, newInstance);
}
When we run the test written above testAuthorizedPut then it throw below error :
java.lang.AssertionError:
Expected: <MyResource(id=null, metadataTemplate=null, name=null, shortLabel=null, description=null, embedInObject=false, optional=false, type=null, possibleValues=null)>
but: was null
at org.hamcrest.MatcherAssert.assertThat(MatcherAssert.java:20)
at org.hamcrest.MatcherAssert.assertThat(MatcherAssert.java:8)
at org.openskye.resource.AbstractUpdatableResourceTestBase.testAuthorizedPut(AbstractUpdatableResourceTestBase.java:42)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:75)
at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:86)
at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:84)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:254)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:89)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:193)
at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:74)
at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:211)
at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:67)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at com.intellij.rt.execution.CommandLineWrapper.main(CommandLineWrapper.java:121)
BUT when I write resource class PUT as, means return newInstance separate solve the above error:
public MyResource update(#PathParam("id") String id, MyResource newInstance) {
super.update(id, newInstance);
return newInstance;
}
So what is the difference of returning newInstance with super calls OR separate call. How can this error resolved without above changes?
code from inherited Update() method would be apreciated.
And, well, you return recieved object from method in one case and in the second you return object from method parameter in that same method.
And the answer to your question lies in super.update() blackBox.
For all I know it could be
MyResource update(){
return null;
}
and this would explain the output. You should inspect why super.update returned null.

Categories

Resources