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());
}
Related
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.
With the logic of TDD in mind and trying to understand how to write unit test's, I am having trouble with Kotlin object. The test pass but I am unsure if this is actually the right test. I am trying to make sure that the Logger.i() method is called and that it saves into the database. But at the moment I am stuck at just its called part.
My Object
object Logger {
fun i(tag: String, msg: String, tr: Throwable? = null): Int {
insertIntoLogDatabase(createLogModel("i", tag, msg, tr))
return if (BuildConfig.DEBUG) Log.i(tag, msg, tr) else 0
}
private fun insertIntoLogDatabase(log: LogModel) {
//Insert into Log DB
logRepo.upsert(log)
}
private fun createLogModel(type: String, tag: String, msg: String, tr: Throwable?) = LogModel(0, type, tag, msg, if (tr != null) tr.message + "\n" + tr?.stackTrace.contentToString() else null)
fun setLogRepo(logRepo: LogRepository) {
this.logRepo = logRepo
}
}
with this, I know that I have to call Logger.setLogRepo(logRemp) to give the Logger access to the repo (and this works)
Where I am stuck is I am trying to unit test the Log.i method call
I have this
#Mock
lateinit var log: Logger
#Before
fun setUp() {
MockitoAnnotations.initMocks(this)
Logger.setLogRepository(logRepo)
}
#Test
fun `log i failed`() {
// When
log.i("Test", "Test1")
// Then
verify(log, times(1)).i("Test", "Test1")
}
I mean this works but is it correct (my gut tells me that something is wrong that I am not actually testing the Logger.i() method
please advise.
Thanks.
As you mentioned, you have to test that when you log the data, it should get stored in the repo in the format you want, and you want to test basically that when you have given the work of sending log to the Logger, it is getting sent to the repository in the correct format and you will assert against that.
So you're test case will look like,
#Mock
lateinit var logRepo: LogRepository
#Before
fun setUp() {
MockitoAnnotations.initMocks(this)
Logger.setLogRepository(logRepo)
}
#Test
fun `when an item is logged, it gets stored in the repository`()
{
val expectedData= <valueThatShouldBeSentToRepo>
Logger.i("Test", "Test1")
verify(logRepo).upsert(expectedData)
}
I wrote simple method that executes tests in my test classes: DataContainerTest.class, AnotherTest.class.
public static void main(String [] args) throws Exception {
Result result = JUnitCore.runClasses(DataContainerTest.class, AnotherTest.class);
System.out.println(result.getRunCount());
System.out.println("Total number of tests " + result.getRunCount());
System.out.println("Total number of tests failed: " + result.getFailureCount());
for(Failure failures : result.getFailures()){
System.out.println(failures.getMessage());
}
System.out.println(result.wasSuccessful());
}
This method doesn't work for my another class CommandsTest.class, where i'm using annotation #RunWith(PowerMockRunner.class). See output below:
1
Total number of tests 1
Total number of tests failed: 1
No runnable methods
false
Here is the sample of the CommandsTest.class
#RunWith(PowerMockRunner.class)
#PrepareForTest({Helper.class,
UtilsPlatform.class,
SessionManager.class,
DataContainerTest.class,
FieldObserver.class,
android.util.Log.class})
public class CommandsTest {
private static Commands2 commands;
private static License mockedLicense;
private static HSQL hsql;
#BeforeClass
public static void setUpStatic() throws Exception {
commands = new Commands2();
PowerMockito.mockStatic(UtilsPlatform.class);
PowerMockito.when(UtilsPlatform.isTablet()).thenReturn(true);
PowerMockito.mockStatic(android.util.Log.class);
PowerMockito.mockStatic(FieldObserver.class);
PowerMockito.doNothing().when(FieldObserver.class, "put", Mockito.anyInt(),
Mockito.anyInt(), Mockito.anyInt(), Mockito.anyInt(), Mockito.any(Session.class));
hsql = PowerMockito.mock(HSQL.class);
PowerMockito.when(hsql, "OnCaseOpen", Mockito.anyInt(), Mockito.anyInt(),
Mockito.anyInt()).thenReturn(false);
mockedLicense = PowerMockito.mock(License.class);
}
#Before
public void setUp() throws Exception {
PowerMockito.mockStatic(SessionManager.class);
PowerMockito.mockStatic(Helper.class);
PowerMockito.doNothing().when(Helper.class, "writeToFile", Mockito.anyString(),
Mockito.any(SocketException.class));
PowerMockito.when(Helper.class, "getLicense").thenReturn(mockedLicense);
PowerMockito.doNothing().when(Helper.class, "fieldOpened", Mockito.anyString(), Mockito.anyString());
}
#Test
public void sendKeyCombinationEventTest_nullParameters_returnOne(){
Assert.assertEquals(1, commands.sendResponse());
}
#Test
public void sendKeyCombinationEventTest_registredGuisNotNullAndOneIsLocal_returnOne(){
Assert.assertEquals(1, commands.sendKeyCombinationEvent());
}
While pressing run button in AndroidStudio, all tests are passed but my own TestRunner cannot run tests in this class.
The best way to handle classes using #RunWith(PowerMockRunner.class) annotation is just put them into default test source of your android project and then run all tests via gradle test. You don't actually need to write own test runner.
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