联系方式

  • QQ:99515681
  • 邮箱:99515681@qq.com
  • 工作时间:8:00-21:00
  • 微信:codinghelp

您当前位置:首页 >> Python编程Python编程

日期:2021-10-28 10:49

Programming 3 - Exercise 2

In this exercise, the main goal will be to configure our project in IntelliJ with Git so we can use version control

on our source code, and write unit tests to ensure that our ephemeral database works correctly.

Git

Initialize a git repository inside your IntelliJ project. You can do this either using the command line or using

IntelliJ’s GUI by going into the menu VCS -> Enable Version Control Integration.

Now the menu VCS will have more options:

Currently the git repository created by IntelliJ is empty.

Every file in the project tree will have a color determining its status within the code repository. Files in red are

files that have been modified since the last commit. Since our repository doesn’t contain any file, they appear

in red.

When right clicking on a file, we also have access to a sub-menu VCS providing specific actions for that file.

Before committing, we need to tell Git which files we want to commit.

Ideally, we should only add files that are needed for someone else to compile the project. For example, it is not

necessary to add and commit binaries produced by the IDE. For us, we only need to commit the source files

(.java files) and Maven’s pom.xml which contains the instructions to build the project.

The files added will appear in green and your tree structure should look like this:

You can now commit your changes by going into VCS -> commit or using the keyboard shortcut Ctrl + K:

The left panel of IntelliJ should change and show you the list of files that will be committed in green and those

that won’t in red (1 in the screenshot below). At the bottom there will be a text field in black (2 in the

screenshot below) where you can enter a commit message. You should enter a message that describes what

your change (i.e. commit) does. Once done you can click on the commit button (3 in the screenshot below).


Ideally, you should regularly commit your changes so that you save your progress and can go backward if

needed.

You can go back to the list of project files clicking on the left panel (1 in screenshot) and the files that you

committed should now appear in white (2 in screenshot).

Generating your first unit test

To finish the version 0.1 of ChatSys, we need to ensure that the in-memory database we implemented during

the previous exercise works correctly. While you can test your code writing a class with a main method, it is

better to use unit tests. These can be easily rerun and are usually stored separately than the main source code

(in the “test” folder when working with Maven).

The goal of this exercise is to write a class InMemoryDatabaseTest that will contain the unit tests for the class

InMemoryDatabase. IntelliJ provides the possibility to generate a test class using the contextual action menu

(Right click on class name -> Show Context Actions, or Alt + Enter).

A window open allowing you to choose which testing library to use, which methods to test and few other

parameters. Start by creating a test for the method authenticate using Junit5 and also generate the setUp and

tearDown methods.

Once you click Ok, IntelliJ will ask you whether you want to add the test file to Git. (You can accept or refuse

and do it manually later.)

Configuring Maven for JUnit5 and running the tests

You should notice that the class you just created cannot be compiled. This is because IntelliJ builds your project

using Maven, and Maven doesn’t know from where to obtain the testing library (JUnit5). You can use the

contextual action menu on the error you get (Right click -> Show Context Actions or Alt + Enter) and ask IntelliJ

to add a Maven dependency.

If you open your pom.xml file, you will notice that it has been updated with a dependency to JUnit but the files

cannot compile. We need to tell IntelliJ to reload the Maven project and download the jar file of the

dependency we added. You should be able to do this with the “Load Maven Changes” icon that appears on the

right.

If you don’t have the icon, you can open the Maven panel on the right side of IntelliJ and click the icon to

reload all Maven projects:

IntelliJ should now be able to compile your project and you should be able to run your (empty) unit test class:

A panel at the bottom should open and you show that the tests successfully ran. This is because we haven’t

written any code inside the test method that IntelliJ generated.

Writing the first unit test

Now we will fill the inside of the unit test for the authenticate method. In this test, we want to test 3 different

behaviors:

• That the authenticate method returns true if we provide the username of an existing user with a

correct password

• That the authenticate method returns false if we provide the username of an existing user with an

incorrect password

• That the authenticate method returns false if we provide the username of a user that doesn’t exist in

the database

For that, we will call three times the method authenticate of InMemoryDatabase with different parameters,

correspond to the three cases defined above, and verify that the values are true or false using the JUnit

methods assertTrue and assertFalse.

However, before calling these methods, we need to have a database object available.

One solution would be to create one InMemoryDatabase object as a local variable inside the method and add

one user to it before calling JUnit’s assert methods:

However, we will also want to test more than one method. If we want to use the same test database and not

have to create one for every tests, the other methods need to have access to the object created.

One solution could be to store the database as a class variable rather than a local variable and initialize it inside

a constructor. However, some of our methods will also modify the database (e.g. register). This will be

problematic if we add a user Jane Doe and the test for the method register runs before the test for the

authentication.

To solve this problem, we can use the method setUp that IntelliJ has generated and that will be executed

before every single test. In this method, we will create a new database and add one user to it. This will allow us

to have the exact same database at the beginning of every test, even if we modify the test database.

Your code should look like this:

(Note: the example above also contains a call to the close method of the database inside the tearDown method

which is called after every test). This isn’t necessary in the current version of ChatSys as there is no open

connection to an actual database. Later it will be necessary to do this when we will use a SQL database,

otherwise, we might encounter errors. Thus, it is a good practice to already make sure we close the connection

at the end of each test.)

You can now run the test. If it passes, it most likely means that your implementation of the method

authenticate is correct. If not, it most likely means you made a mistake.

Testing the other methods of InMemoryDatabase

If your test for the authenticate method runs successfully, you can now commit your changes with Git and start

working on the other tests. Before adding more tests, we will add a message in the test database inside the

setUp method. It’s also a good practice to name the test methods starting with the word test to differentiate

the method from the one in the InMemoryDatabase. Rename the method authenticate of the class

InMemoryDatabaseTest as “testAuthenticate”. Your code should look like this:

You should now implement tests for the other methods of InMemoryDatabase. The followings are some

suggestions of tests you can implement:

• testNewDatabase: Test that the database created by the setup method contains only one user and one

message.

o You can do this by calling the methods getNumberUsers and getNumberMessages of

InMemoryDatabase and two calls to JUnit’s assertEquals method.

• testGetRecentMessages: test that the result of a call to getRecentMessages returns a list with a single

ChatMessage object

o Check that this behavior works if you set the parameter of getRecentMessages to 1

o Check that this behavior works if you set the parameter to a higher value. (The method should

return only one message as there is only one message in the database)

o Check that the values of the username and the chat message are correct.

• testRegister

o Check that if you try to register the user “johndoe” again, the method register returns false and

the number of users in the database is still one.

o Check that if you try to register another user (e.g. “janedoe”), the register methods returns

true and the number of user in the database is now 2.

o Check that if you try to register the same user (e.g. “janedoe”) once more, the register method

returns false and the number of users in the database is still 2.

• testAddMessage

o Check that if you try to add a different message sent by johndoe, the message is effectively

added to the database

o Make sure that the timestamp of the new message sent is more recent than the time stamp of

the first message that was added. (You can do this using the compareTo method of the class

Timestamp)

o Check that calling getRecentMessages with a parameter n greater than one returns a list of two

messages, with the first element being the message sent inside the setUp method (“Hello

World!”) and the second the one sent in the testAddMessage method.

Your tests should run successfully and the outcome should look like this:

Question: How would you write a unit test for the method getUnreadMessages? Describe the scenario and the

different assert methods from JUnit that you would call.

Testing incorrect behavior

The method addMessage should throw an IllegalArgumentException if the username of the message doesn’t

correspond to an existing user in the database.

Write a test method “testAddMessageInvalidUser” testing this specific behavior. Inside this method, simply try

to call db.addMessage("not_registered", "Message won't be added");

Run your tests and you should observe that the test fails:

Question: How can you use JUnit to make have a successful test (e.g. appears in green) checking that the

method throws the correct exception?

Using Maven to build a jar

Once your tests are running correctly, you should commit your changes and build a jar with Maven.

Using the Maven panel on the right side of IntelliJ, you can create a jar by running the “package” command of

Maven. This will also run the unit tests to make sure they pass successfully.

If the build was successful, you should find a jar file inside the target folder of your project:

Optional exercise 1

Write unit tests for the class ClosableInMemoryDatabase. As both ClosableInMemoryDatabase and

InMemoryDatabase implements the Database interface, their behavior should be similar. This means that it

should be theoretically possible to write a single set of test cases and reuse them for both classes.

Question: How can you utilize polymorphism so that you can create unit tests for ClosableInMemoryDatabase

without needing to write or copy paste a lot of code (e.g. less than 10 lines of code)?

Optional exercise 2

Write the Javadoc of your current implementation.


版权所有:编程辅导网 2021 All Rights Reserved 联系方式:QQ:99515681 微信:codinghelp 电子信箱:99515681@qq.com
免责声明:本站部分内容从网络整理而来,只供参考!如有版权问题可联系本站删除。 站长地图

python代写
微信客服:codinghelp