I have a problem with Unit Tests in Java.
I put here my code and my error. On internet I found this is a problem with hashcode. I need to recreate them but I don't know why and how.
My method :
public void setGroupModel(GroupModel groupModel) {
this.groupModel = groupModel;
this.groupModel.add(this);
}
cellControler file :
public class CellController {
public void click(CellModel cellModel, HexModel hexModel)
{
GroupModel groupModel = new GroupModel();
cellModel.setGroupModel(groupModel);
hexModel.getGridContentModel().getArrayListGroupModel().add(groupModel);
}
}
My UnitTest :
public class CellControllerTest {
protected CellController cellController;
#Before
public void setUp() throws Exception {
cellController = new CellController();
}
#After
public void tearDown() throws Exception{
}
#Test
public void testClick() throws Exception{
GroupModel groupModel = new GroupModel();
CellModel cellModel = new CellModel();
HexModel hexModel = new HexModel(); // hexModel has an attribute : gridContentModel
cellController.click(cellModel, hexModel);
assertEquals(groupModel, cellModel.getGroupModel());
}
}
My error
java.lang.AssertionError: expected:<model.GroupModel#6d5380c2> but was:<model.GroupModel#45ff54e6>
I think the problem is : this.groupModel = groupModel;
What I have to write and why? :)
To compare is easy, you need to override hashCode and equals or use a comparator, if you did not do that then the message you get is perfectly normal.
Here you set the groupModel AND modify the groupModel.
public void setGroupModel(GroupModel groupModel) {
this.groupModel = groupModel;
this.groupModel.add(this); // the modification
}
In your test you compare the groupModel you just created and the groupModel that you get from cellModel.getGroupModel(), but that one has been modified, so the two objects are different
assertEquals(groupModel, cellModel.getGroupModel());
Related
I try to write my own JUnit 5 extension, providing some simple information about test duration.
I also want to print out the repetition information but how can I access these informations in the extension?
Are there any simple ways instead of reflection or writing and parsing the numbers to the display name?
simple example:
#ExtendWith(TimingExtension.class)
public class MyTestClass {
#RepeatedTest(value = 5, name = "{currentRepetition}/{totalRepetitions}")
public void myTest(TestInfo testInfo, RepetitionInfo repInfo) {
// do some work here...
}
}
public class TimingExtension implements AfterTestExecutionCallback {
#Override
public void afterTestExecution(ExtensionContext context) throws Exception {
if(context.getRequiredTestMethod().getDeclaredAnnotation(RepeatedTest.class) != null) {
System.out.println("This was test X of Y"); // how to get currentRepetition and totalRepetitions here?
}
}
}
Unfortunately there is no support for parameter injection in extensions. It's only one way. So in order to get RepetitionInfo in your TimingExtension you have to set it.
First you need to use #RegisterExtension e.g.
public class MyTestClass {
#RegisterExtension
TimingExtension timingExt = new TimingExtension();
#RepeatedTest(value = 5, name = "{currentRepetition}/{totalRepetitions}")
public void myTest(TestInfo testInfo, RepetitionInfo repInfo) {
timingExt.setRepetitionInfo(repInfo);
// do some work here...
}
}
public class TimingExtension implements AfterTestExecutionCallback {
private RepetitionInfo repInfo;
#Override
public void afterTestExecution(ExtensionContext context) throws Exception {
if (context.getRequiredTestMethod().getDeclaredAnnotation(RepeatedTest.class) != null && repInfo != null) {
System.out.println(String.format("This was test %d of %d", repInfo.getCurrentRepetition(), repInfo.getTotalRepetitions()))
repInfo = null;
}
}
public void setRepetitionInfo(RepetitionInfo repInfo) {
this.repInfo = repInfo;
}
}
I am very new to JUnit testing and I am trying to understand how to test the instantiation of an class.
Let us say that I have the following ToyBox class which needs an ArrayList<Toy> in order to be instantiated. This list of toys is created on another part of the program, of course, but I do not understand very well where I should create it in order to unit test ToyBox.
ToyBox Class
public ToyBox(ArrayList<Toy> toyList){
this.toys= toyList;
for (Toy toy: toyList) {
checkToy(toy);
}
}
private void checkToy(Toy toy){
if (toy.isRed()){
this.numRed += 1;
} else {
this.numBlue += 1;
}
}
public int getBlues(){
return this.numBlue;
}
ToyBoxTest
public class ToyBoxTest {
#Test
public void getNumBlues() throws Exception {
// assert that num blues corresponds
}
Where should I instantiate the ToyBox class in order to perform the getNumBlues() method?
Should it be like this?
public class ToyBoxTest {
ArrayList<Toy> toyList = new ArrayList<Toy>();
Toy toy1 = new Toy("blue", "car");
Toy toy2 = new Toy("red", "bike");
toyList.add(toy1);
toyList.add(toy2);
#Test
public void getNumBlues() throws Exception {
// assert that num blues corresponds
ToyBox box = new ToyBox(toyList);
assertEquals(1, box.getBlues());
}
Basically, my question is where and how should I create the arraylist of objects needed to test a class that depends on that created list.
Most tutorials will state that the best practice is to instantiate the object you're about to test in a setup method (a #Before method in JUnit's terminology). However, your usecase doesn't fit this pattern well. As your constructor holds all the logic, you should instantiate the object in the test itself, and then assert that getNumBlues() and getNumReds() return the correct results. E.g.:
#Test
public void bothColors() throws Exception {
ArrayList<Toy> toyList = new ArrayList<>(Arrays.asList
new Toy("blue", "car"),
new Toy("red", "bike"));
ToyBox box = new ToyBox(toyList);
assertEquals(1, box.getBlues());
}
#Test
public void justBlues() throws Exception {
ArrayList<Toy> toyList = new ArrayList<>(Arrays.asList
new Toy("blue", "car"),
new Toy("blue", "bike"));
ToyBox box = new ToyBox(toyList);
assertEquals(2, box.getBlues());
}
// etc...
I made a super simple example that doesn't make any sense.
public static void main(String [] args) throws IntrospectionException {
BeanInfo info = Introspector.getBeanInfo(DemandBidType.class);
int breakpoint = 0;
}
Here's my class:
public class DemandBidType {
protected Boolean isDuplicateHour;
protected Boolean test;
public boolean isIsDuplicateHour() {
return isDuplicateHour;
}
public void setIsDuplicateHour(Boolean isDuplicateHour) {
this.isDuplicateHour = isDuplicateHour;
}
public Boolean getTest() {
return test;
}
public void setTest(Boolean test) {
this.test = test;
}
}
And here is a screen shot showing the problem; the field I care about isn't being recognized as having a write method. I added another field 'test' and that one works fine... There was very little related to this on Google, and what was there was years old with older java versions. You can see in the bottom right that I'm using 1.7.51.
(http://i.stack.imgur.com/DKC6e.png)
It turns out it's because the return type of the getter doesn't match the argument of the setter. (One's "Boolean" the other "boolean").
Hi I saw some of the related question related to this but didn't find any to the point solution.
I have a POJO class defined as:
MpsPojo.java
public class MpsPojo {
private String mfr;
private String prod;
private String sche;
public String getMfr() {
return mfr;
}
public void setMfr(String mfr) {
this.mfr = mfr;
}
public String getProd() {
return prod;
}
public void setProd() {
this.prod = prod;
}
public String getSchema() {
return sche;
}
public void setSchema() {
this.sche = sche;
}
}
I have 2nd business Logic as:: MpsLogic.java
public class MpsLogic {
public void calculateAssert(MpsPojo mpspojo){
String manufacturer;
String product;
String schema;
manufacturer = mpspojo.getMfr();
product = mpspojo.getProd();
schema = mpspojo.getSchema();
String url = "http://localhost:9120/dashboards/all/list/"+manufacturer+"/"+product+"/"+schema;
}
}
And final class, the Test class is :: FinalLogic.java
public class FinalLogic {
MpsPojo mpspojon = new MpsPojo();
MpsLogic mpslogicn = new MpsLogic();
#Test
public void firstTest() {
mpspojon.setMfr("m1");
mpspojon.setProd("p1");
mpspojon.setSchema("sch1");
mpslogicn.calculateAssert(mpspojon);
System.out.println("Printing from Final class");
}
}
In program FinalLogic.java, this gives me the Compilation error error method setSchema in class MpsPojo cannot be applied to given types;
But when I comment the lines mpspojon.setProd("p1"); and mpspojon.setSchema("sch1"); then this works fine without error.
I debugged a lot but dint find any clue for this. Any help will be very helpful for me.
Thanks
Add String arguments to setProd and setSchema as you have already done with setMfr:
public void setProd(String prod) {
^ ^
and
public void setSchema(String sche) {
^ ^
setSchema() receives no parameters in your declaration. Change it to:
public void setSchema(String sche) {
this.sche = sche;
}
Same holds true for setProd
If you use any IDE, I advise you:
look into the warnings that you will get (the assignment this.sche = sche will give warning The assignment to variable thing has no effect in case of no argument method).
Generate the setters/getters automatically, don't code them by yourself (thus avoiding any possible typing mistakes). E.g. in Eclipse that will be alt+shift+s, then r
I am creating a test suite for my android application and have this setUp method
private static final String TAG_NAME = "TESTING_SUITE";
public TestingMusicDAO musicDAO;
public List<Song> songs;
public Instrumentation instr;
MusicService musicService;
#Override
public void setUp() throws Exception {
instr = this.getInstrumentation();
Log.d(TAG_NAME, "Setting up testing songs");
musicDAO = new TestingMusicDAO(instr.getContext());
musicService = new MusicServiceImpl(musicDAO);
musicDAO.getAllSongsFromFile();
songs = musicDAO.getAllSongs();
for(Song song : songs)
Log.d( TAG_NAME, song.toString() );
}
And then have these tests which are created by a python tool from a text file
public void test1() {
List<Song> testPlaylist;
String testArtist = ("The Beatles");
String actualArtist = ("TheBeatles");
testPlaylist = testingPlaySongsByKeyword(testArtist);
if(testPlaylist.isEmpty()){
fail("No Songs Were Found");
} else {
for( Song loopsongs : testPlaylist){
if (!(loopsongs.getArtist().equals(actualArtist))){
fail("Song Doesnt Contain the artist" + actualArtist + "... Contains ->" + loopsongs.getArtist());
}
}
}
}
and every time one of these gets called the musicDAO is regenerated. How can I stop the setup method from being called
You don't. The design of JUnit is that setUp() and tearDown() are done once per test. If you want it done per class, do it in the constructor. Just make sure that you don't alter anything inside the classes. The reason for doing it once per test is to make sure all tests start with the same data.
You could use #BeforeClass and #AfterClass annotations from JUnit.
#BeforeClass
public static void test_setUp_Once(){
// Code which you want to be executed only once
createDb();
}
#AfterClass
public static void test_tearDown_Once(){
// Code which you want to be executed only once
deleteDb();
}
Note: You need to declare these methods static to work properly.
I had the same basic problem. I want to be able to test the structure of my database, so I create it in the setUp method and delete it in the tearDown. Using the constructor wouldn't solve my need to delete the database once all my tests are executed, so I used some reentrant logic:
static int testsExecutedSoFar = 0;
static boolean isFirstRun = true;
#Override
protected void setUp() throws Exception {
if(isFirstRun){
createDb();
isFirstRun = false;
}
}
#Override
protected void tearDown() throws Exception{
testsExecutedSoFar++;
if (testsExecutedSoFar == totalNumberOfTestCases())
deleteDb();
}
private int totalNumberOfTestCases() {
return countTestCases()+1; //have to add one for testandroidtestcasesetupproperly added by AndroidTestCase
}
The fields have to be static since JUnit creates a new instance of the class for each run. The magic 1 had to be added since AndroidTestCase adds it's own test (testandroidtestcasesetupproperly) to the test suite but it doesn't count towards the number returned by countTestCases().
A bit on the ugly side, but it did the trick.