-1
    public class Room extends java.lang.Object implements java.io.Serializable {

            public String description;
            public Map<String, Room> map;
            public List<Thing> things;

            //Room
            //Parameters:
            //desc - Description for the room Note: any newlines in desc will be 
            replaced with *

            public Room(java.lang.String desc){
                this.description = desc;
            }
            //getDescription
            //A description of the room
            //Returns:
            //Description

            public java.lang.String getDescription(){
                return description;
            }
            //replaceLine
            //any new line in s will be replaced with *

            public String replaceLine(String s){
                return s.replace("\n", "*");
            }

            //setDescription
            //Change Room description Note: any newlines in s will be 
            //replaced with *
            //Parameters:
            //s - new Description

            public void setDescription(java.lang.String s){
                    this.description = replaceLine(s);
            }
}

I am trying to write a Junit test for the last method:

@Test
    public void setDescription(java.lang.String s) {
        String input = "abc\n";
        String expected = "abc";
        setDescription(input);
        assertEquals(expected, input);
    }

I know that it is not correct but I have no idea how to fix it. I am pretty new to Java and coding as a whole. Could someone please help me with this?

James
  • 5
  • 1
  • 2
  • 5
  • How are you constructing `Room` object in tests? – Thiyagu Mar 28 '18 at 11:31
  • 1
    Why do you expect `"abc"` when it will be `"abc*"` ? – LenglBoy Mar 28 '18 at 11:33
  • 1
    UnitTests verify *public observable behavior* of a unit, that is: *return values* and *communication with dependencies*. A *setter* method only changes the *internal state* of an object which we do not verify. – Timothy Truckle Mar 28 '18 at 11:33
  • @TimothyTruckle I would say it is publically observable as we have a getter – Thiyagu Mar 28 '18 at 11:36
  • 2
    @user7 getter doesn't matter - it shouldn't be tested. Here you might want to test it for different reason - it's not just setter, it has a logic inside. https://stackoverflow.com/questions/6197370/should-unit-tests-be-written-for-getter-and-setters – Jaroslaw Pawlak Mar 28 '18 at 11:37
  • @user7 a "getter" is a violation of the most important OO principle: *Information hiding/Encapsulation* it is only acceptable for *data transfer object* (DTOs) or *value objecst* which have no logic (accept very basic validations). – Timothy Truckle Mar 28 '18 at 11:51
  • @TimothyTruckle True. Here the Room class seems to be a simple POJO except the fact that the setter has business logic – Thiyagu Mar 28 '18 at 11:54
  • @LenglBoy hey man that is my mistake I should expect "abc*" like you said. Thanks everyone. – James Mar 28 '18 at 12:19

3 Answers3

1

Lets assume you have created a Room instance for the test class.

...
Room room = new Room("test room");
...
@Test
public void testSetDescription() {
    assertEquals("abc", room.setDescription("abc"));
    assertEquals("abc*", room.setDescription("abc\n"));
}

You can add more such assertions based on your expectations. How setDescription handles empty string or a null input; all such use cases can be asserted in your UT.

BTW, you don't have to explicitly extend Object. Every class extends from Object implicitly either directly or indirectly through inheritance. You also don't have to use the fully qualified names of anything in java.lang package. They are implicitly imported. Also, if replaceLine should be part of the public API, you may want to add similar unit test case for that, for example public void testReplaceLine() {...}. Welcome to Java programming!

Amudhan
  • 696
  • 8
  • 18
  • I tried your help as well and it doesn't like it either :( https://i.imgur.com/z6tkVLt.png – James Mar 28 '18 at 11:59
1

Here is your test:

@Test
  public void testSetDescription() {
    Room instance = new Room("test");
    instance.setDescription("abc\n");
    assertEquals("abc*", instance.getDescription());
  }

The assertEquals method is oveloaded and can be used in many ways. In this case we set in first place the expectation an on the second place what we really have (actual data) from the object. But in real life, most useful test is a test which check only single method, but in your case you call for one method but actually test other method. In real project you shouldn't test getters and setters. Only business logic, because if you'll test each method you will newer have time for main code.

Aleksandrs Rudzitis
  • 661
  • 4
  • 9
  • 30
  • It work like a charm thanks Aleks, but do you know why it is not work if I do this when I put testSetDescription(java.lang.String s)? https://i.imgur.com/KtFqnGg.png – James Mar 28 '18 at 12:08
  • It work. but in your code you expect "abc\n" instead of "abc*" like in your code: `s.replace("\n", "*");` – Aleksandrs Rudzitis Mar 28 '18 at 12:11
  • 1
    If you want write test, you must ask few question for your self: 1 - What I need to test? 2 - What argument I need to pass in to the method? 3 - What the result I expect. – Aleksandrs Rudzitis Mar 28 '18 at 12:13
-1

I didn't get the problem. Could you post the error?

In the first class the replaced with * is outside the comment block, you must put // before that sentence

The Unit test aren't testing your Room class, you must do something like this:

@Test
public void testDescription(java.lang.String s) {
    String input = "abc\n";
    String expected = "abc";

    //create your Room instance 
    Room myRoom = new Room(input);//why using a constructor with description if you set the description after?
    //set the description in your Room instance
    myRoom.setDescription(input);

    //test your set-get Description against your expected result
    assertEquals(expected, myRoom.getDescription());
}
Amir
  • 8,821
  • 7
  • 44
  • 48
ki113r
  • 1
  • 1
  • I tried your help and it come up to this :( https://i.imgur.com/LJQWR0u.png – James Mar 28 '18 at 11:57
  • Sorry man I think after I left (java.lang.String s) out of the testDescription (), it work. Put I thought I have to put that in as in my method I have it? – James Mar 28 '18 at 12:06
  • Just need to check expected = "abc*" – LenglBoy Mar 28 '18 at 12:26
  • I think you are confusing the JUnit Test objective. You have to test your Room class. You set the description and you have to test if the getDescription() have the expected result. You don't need to have set's and get's in your test... your test method don't need to have parameters cause you are defining the input and the expected strings inside the test. "public void testDescription()" should be enough (thanks Amir for the english corrections) – ki113r Mar 28 '18 at 17:18