im new to unit testing. I am using junit5 for an aem 6.5 application. Im trying to write unit test so that i can migrate to cloud which has a requirement of atleast 50% unit test, thus what im doing now. My code has an init method for the getTags(). My unit test works fine but the jacoco reports a line that is not being covered. Any help would be appreciated to pint me in the right direction.
I have this class:
#Self
private SlingHttpServletRequest request;
#ValueMapValue
private List<String> tags;
#Override
public String getExportedType() {
return RESOURCE_TYPE;
}
#PostConstruct
public void init() {
Resource tagsNode = request.getResource().getChild("tags");
tags = new ArrayList<>();
if (tagsNode!=null) {
for (Resource child : tagsNode.getChildren()) {
TagModel tag = child.adaptTo(TagModel.class);
tags.add(tag.getTag());
}
}
}
public List<String> getTags() {
return this.tags;
}
And i have this unit test for aem
#Test
void testGetTags() {
List<String> expected = new ImmutableList.Builder<String>()
.add("4")
.add("22")
.build();
ctx.currentResource("/content/blog_placeholder");
BlogPlaceholderModel blogPlaceholderModel = ctx.request().adaptTo(BlogPlaceholderModel.class);
List<String> actual = blogPlaceholderModel.getTags();
assertEquals(expected, actual);
}
#Test
void testGetExportedType() {
final String expected = "furniture-row/components/content/blog-placeholder";
ctx.currentResource("/content/blog_placeholder");
BlogPlaceholderModel blogPlaceholderModel = ctx.request().adaptTo(BlogPlaceholderModel.class);
String actual = blogPlaceholderModel.getExportedType();
assertEquals(expected, actual);
}
For some reason my test is not covering the if condition:
what am i missing ? thanks
Your tests are covering this line partially.
You do have a test for the case that (tagsNode != null) == true but not for (tagsNode != null) == false. Therefore, the line is yellow to indicate that not all "branches" of the if statement are covered.
Related
When I try to test a spring cloud stream function based method, it always happens NullPointerException about InputDestination.
I have two questions:
It's hard for me to know how to write UT from the official doc. official test doc
Besides, how to write integration Test if test file has some dependencies. It seems create a new context and always has NoSuchBeanDefination error.
I have tried as flow, but the context can not find some dependency beans.
#Test
public void sampleTest() {
try (ConfigurableApplicationContext context = new SpringApplicationBuilder(
TestChannelBinderConfiguration.getCompleteConfiguration(
MyTestConfiguration.class))
.run("--spring.cloud.function.definition=uppercase")) {
InputDestination source = context.getBean(InputDestination.class);
OutputDestination target = context.getBean(OutputDestination.class);
source.send(new GenericMessage<byte[]>("hello".getBytes()));
assertThat(target.receive().getPayload()).isEqualTo("HELLO".getBytes());
}
}
So I just want to write UT, but still have NPE.
Here is my code.
#Bean
public Function<Message<List<DemoBean>>, Message<DemoBean>> findFirstBean( ){
return message -> {
List<DemoBean> demoBeans = message.getPayload();
return MessageBuilder.withPayload(demoBeans.get( 0 )).build();
};
}
Here is my test.
#SpringBootTest
#ActiveProfiles(profiles = "local")
#Import({ TestChannelBinderConfiguration.class})
class FunctionDemoTest {
#Autowired
private InputDestination inputDestination;
#Autowired
private OutputDestination outputDestination;
private FunctionDemo functionDemo;
// some dependency need to mock
private DemoService demoService;
#BeforeEach
void setUp() {
demoService = Mockito.mock( DemoService.class );
functionDemo = new FunctionDemo( demoService);
}
#Test
public void findFirstBeanTest() {
DemoBean demoBean = new DemoBean();
demoBean.setName("Howard");
demoBean.setAge( 1 );
DemoBean demoBean1 = new DemoBean();
demoBean1.setName("Frank");
demoBean1.setAge( 2 );
List<DemoBean> demoBeanList = new ArrayList<>();
demoBeanList.add( demoBean );
demoBeanList.add( demoBean1 );
Message<List<DemoBean>> inputMessage = MessageBuilder.withPayload(demoBeanList).build();
inputDestination.send(inputMessage,"findFirstBean-in-0");
Assertions.assertNotNull( outputDestination.receive( 10000, "findFirstBean-out-0") );
}
}
Here is error:
java.lang.NullPointerException: while trying to invoke the method org.springframework.messaging.SubscribableChannel.send(org.springframework.messaging.Message) of a null object returned from org.springframework.cloud.stream.binder.test.InputDestination.getChannelByName(java.lang.String)
at org.springframework.cloud.stream.binder.test.InputDestination.send(InputDestination.java:89)
at com.successfactors.caf.listener.FunctionDemoTest.raePdrResultProcessor(FunctionDemoTest.java:82)
Well, I know the root cause of NPE.
Message<byte[]> receive(long timeout, String bindingName)
It seems should be destinationName instead of bindingName in source code.
Any other answers would be appreciated.
testclass.java
#Test
public void testgetDictionaryValueListById() {
DictionaryValue dictionaryValue = new DictionaryValue();
dictionaryValue.setId(1);
dictionaryValue.setValueName("Test Dictionary Value");
dictionaryValue.setValueKey("12345678");
dictionaryValue.setStatus("Active");
dictionaryValue.setCreatedOn(new Date());
dictionaryValue.setUpdatedOn(new Date());
Mockito.when(dictionaryValueRepo.findById(1).get()).thenReturn(dictionaryValue);
assertThat(dictionaryService.getDictionaryValueListById(1)).isEqualTo(dictionaryValue);
}
Service.java
public DictionaryValue getDictionaryValueListById(int id) {
return dictionaryValueRepo.findById(id).get();
}
Repo.java
#Repository
public interface DictionaryValueRepo extends JpaRepository<DictionaryValue, Integer> {
}
I am getting no such value present again and again on executing test case in testclass.java. I don't know why? but when I am running my service method from the controller it is working as expected - fetching records from the database but not working in a test case.
Your test should be like this and please check out the naming. You need to Mock the step findId() befor the `get().
#InjectMocks
Service cut;
#Mock
DictionaryValueRepo dictionaryValueRepoMock;
// Can skipped by adding a #RunWith... on Testclass
#Before
public init() {
Mockito.initMocks(this);
}
#Test
public void testgetDictionaryValueListById() {
// Prepare Data
final int testId = 1;
DictionaryValue dictionaryValue = new DictionaryValue();
dictionaryValue.setId(testId);
dictionaryValue.setValueName("Test Dictionary Value");
dictionaryValue.setValueKey("12345678");
dictionaryValue.setStatus("Active");
dictionaryValue.setCreatedOn(new Date());
dictionaryValue.setUpdatedOn(new Date());
// config mocking
Mockito.when(dictionaryValueRepo.findById(testId)).thenReturn(<VALUE>);
Mockito.when(dictionaryValueRepo.findById(testId).get()).thenReturn(dictionaryValue);
// Call yout method for Testing
cut.getDictionaryValueListById(testId);
// verifies (if wanted) + assertions....
}
I concur with LenglBoy, so the right answer should be given to him.
The thing you need to be careful is what "VALUE" means in this line:
Mockito.when(dictionaryValueRepo.findById(testId)).thenReturn(VALUE);
The findById returns an Optional, so that is what you should build and pass to Mockito. Something like this:
Mockito.when(dictionaryValueRepo.findById(testId))
.thenReturn(Optional.ofNullable(dictionaryValue));
And for a scenario where the id does not exists in BD, passing Optional.empty() should be good enough.
apologized to post this question here but i am in problem suddenly because i need to write unit test code for action where i am not good.
i am bit familiar with asp.net mvc. before i never write unit test code for action rather i manually test the action. now i want to know the art of writing unit test code for my action. so i read couple of article on unit test but notice all article share very basic idea about to write unit test code for action method in mvc controller but i am not being able to write unit test code for my action. so here i am pasting my one sample controller and their actions. so anyone please share knowledge how to write unit test code for my action methods below. if possible discuss with code sample or good hint which enable to write unit test code in VS2013 and MVC version 5.
here is my code
public class StudentController : Controller
{
private StudentRepository _Studentdata;
private StateRepository _Statedata;
private CityRepository _Citydata;
public StudentController()
{
_Studentdata = new StudentRepository(System.Configuration.ConfigurationManager.ConnectionStrings["StudentDBContext"].ConnectionString);
_Statedata = new StateRepository(System.Configuration.ConfigurationManager.ConnectionStrings["StudentDBContext"].ConnectionString);
_Citydata = new CityRepository(System.Configuration.ConfigurationManager.ConnectionStrings["StudentDBContext"].ConnectionString);
//_Studentdata = new StudentRepository(System.Configuration.ConfigurationManager.ConnectionStrings["StudentSQLDBContext"].ConnectionString);
//_Statedata = new StateRepository(System.Configuration.ConfigurationManager.ConnectionStrings["StudentSQLDBContext"].ConnectionString);
//_Citydata = new CityRepository(System.Configuration.ConfigurationManager.ConnectionStrings["StudentSQLDBContext"].ConnectionString);
}
// GET: Stuent
public ActionResult List(StudentListViewModel oSVm)
{
if (Request.IsAjaxRequest())
System.Threading.Thread.Sleep(1000); // just simulate delay of one second
StudentListViewModel SVm = new StudentListViewModel();
SVm.SetUpParams(oSVm);
SVm.Students = _Studentdata.GetStudents(oSVm.page, oSVm.PageSize, oSVm.sort, oSVm.sortdir).ToList();
SVm.States = _Statedata.GetAll().ToList();
SVm.Cities = _Citydata.GetAll().ToList();
SVm.RowCount = _Studentdata.DataCounter;
return View("ListStudents",SVm);
}
[HttpPost]
public ActionResult UpdateStudents(StudentListViewModel oSVm, string Action)
{
if (Request.IsAjaxRequest())
System.Threading.Thread.Sleep(1000); // just simulate delay of one second
StudentListViewModel SVm = new StudentListViewModel();
SVm.SetUpParams(oSVm);
if (Action == "UPDATE")
{
SVm.Students = _Studentdata.SaveXML(new List<Student>(oSVm.Students).ToXml("Students"),
oSVm.page, oSVm.PageSize, oSVm.sort, oSVm.sortdir).ToList();
}
else if (Action == "DELETE")
{
SVm.Students = _Studentdata.Delete(oSVm.Students[0].ID,
oSVm.page, oSVm.PageSize, oSVm.sort, oSVm.sortdir).ToList();
}
SVm.States = _Statedata.GetAll().ToList();
SVm.Cities = _Citydata.GetAll().ToList();
SVm.RowCount = _Studentdata.DataCounter;
return PartialView("_StudentGrid", SVm);
}
[HttpPost]
public ActionResult RefreshStudents(StudentListViewModel oSVm)
{
if (Request.IsAjaxRequest())
System.Threading.Thread.Sleep(1000); // just simulate delay of one second
StudentListViewModel SVm = new StudentListViewModel();
SVm.SetUpParams(oSVm);
SVm.Students = _Studentdata.GetStudents(oSVm.page, oSVm.PageSize, oSVm.sort, oSVm.sortdir).ToList();
SVm.States = _Statedata.GetAll().ToList();
SVm.Cities = _Citydata.GetAll().ToList();
SVm.RowCount = _Studentdata.DataCounter;
return PartialView("_StudentGrid", SVm);
}
[HttpGet]
public JsonResult GetCityName(int StateID)
{
if (Request.IsAjaxRequest())
System.Threading.Thread.Sleep(1000); // just simulate delay of one second
return Json(new {CityList =_Citydata.GetCityByStateId(StateID)} , JsonRequestBehavior.AllowGet);
}
}
Thanks
My problem is as follows:
I am trying to test multiple unit-tests in my controller in a Play Framework 2.4 application. I figured out I need to use a FakeApplication to run the FakeRequests to my controllers in, but for some odd reason the unit-tests work if I start and stop a new FakeApplication. If I start and stop the same FakeApplication, the first unit-test with a FakeRequest works, and the rest dont.
My question:
What am I doing wrong? Why are my unit-tests working if I start and stop a new FakeApplication, and why are they not working if I start and stop the same FakeApplication?
Here is my code snippet:
UnitTest class:
#Test
public void submitTestCorrectInput() {
final String input = CORRECT_INPUT;
final Result result = doCall(input);
assertThat(result.status(), is(equalTo(Http.Status.OK)));
}
#Test
public void submitTestIncorrectInput() {
final String input = INCORRECT_INPUT;
final Result result = doCall(input);
assertThat(result.status(), is(equalTo(Http.Status.NOT_FOUND)));
}
private Result doCall(final String input, final String max, final String filter) {
final Http.RequestBuilder requestBuilder = Helpers.fakeRequest(routes.Application.submit(input));
return route(requestBuilder);
}
Superclass from unittest class:
#Before
public void setUp() {
Play.start(Helpers.fakeApplication().getWrappedApplication());
}
#After
public void tearDown() {
Play.stop(Helpers.fakeApplication().getWrappedApplication());
}
I have a method like this which I want to unit test
public void update(String collectionName, BasicDBObject query, BasicDBObject updateObj){
try{
DBCollection collection = getCollection(collectionName);
collection.update(query, updateObj, true, false);
} catch (MongoException e) {
if (e.getMessage().startsWith("can't call something")) {
refreshConnection(collectionName);
} else {
throw e;
}
}
}
And the test code is as below. I have tried both the methods in the comments in unit test case and currently have commented it.
#Test
public void testUpdate(){
MongoStore store = PowerMock.createStrictPartialMockForAllMethodsExcept(MongoStore.class, "update");
DBCollection collection = PowerMock.createMock(DBCollection.class);
BasicDBObject updateobj = new BasicDBObject("test","shrikar");
String name = "testcoll";
String id = "123";
BasicDBObject query = new BasicDBObject("id",id);
EasyMock.expect(store.getCollection(name)).andReturn(collection);
//EasyMock.expect(collection.update(EasyMock.anyObject(BasicDBObject.class),EasyMock.anyObject(BasicDBObject.class),EasyMock.anyBoolean(),EasyMock.anyBoolean()));
//EasyMock.expect(collection.update(query,updateobj,true,false));
PowerMock.replayAll();
store.update(name,query,updateobj);
EasyMock.expectLastCall().times(1);
PowerMock.verifyAll();
}
In all the cases I keep getting
Unexpected Method call DBCollection.update({"id":"123"},{"test":"shrikar"}, true, false)
What am I missing?
Ok I found out the problem I had forgotten to add Mongo*.class to PrepareForTest
#PrepareForTest({MongoStore.class,MongoOptions.class,Mongo.class, BasicDBObject.class,DBCursor.class,DBObject.class})