JUnit :: または JavaRush バリデータを愛する方法
なぜこの獣が必要なのかについて簡単に説明します。JUnit は、良いコードまたはあまり良くないコードを自動的にテストするためのフレームワークです。次のように言えます: - なぜこのスイングが必要なのかというと、優れた Java コードを簡単かつ簡単にテストできるからです。導入の歌詞はたくさん書けますが、私はあまり詩人ではないので、本題に取り掛かりましょう...オブジェクトを作成する
したがって、何かをテストするには、まずテスト オブジェクトが必要です。私たちには目の前にある課題があります。- ユーザーに関する情報を保存するオブジェクトが必要です。
- ID - 新しいユーザーが追加された順序でカウントする必要があります。
- ユーザー名。
- 彼の歳。
- 性別男性女性)
-
ユーザーのリストのストレージを提供する必要があります。
-
クラスはそれができなければなりません。
- すべてのユーザーのリストを生成します。
- 性別 (MALE/FEMALE) ごとにユーザーのリストを生成します。
- 一般リスト内のユーザーの数を返し、ユーザーの性別に基づいて数を計算します。
- ユーザーの年齢別に合計金額を計算し、性別も考慮します。
- 全体と性別の両方の平均年齢を計算します。
User
フィールドを含む Java クラスを作成しましょう。
private int id;
private String name;
private int age;
private Sex sex;
ユーザー データを保存するにはこれで十分です。タスクに他に何が必要か見てみましょう。何らかの方法ですべてのユーザーを保存する必要があります。クラスに静的フィールドを作成しましょうallUsers
。そうであれば大丈夫だと思いますMap<Integer, User>
private static Map<Integer, User> allUsers;
また、何らかの方法でユーザーにシーケンス番号を割り当てる必要があります。新しいユーザーの作成時にId
ユーザーにシーケンス番号を割り当てる静的カウンター フィールドを作成しましょう。
private static int countId = 0;
フィールドの整理ができたので、オブジェクトのコンストラクターと、フィールドid
、name
、age
、のゲッターを作成しましょうsex
。ヘテラエについては何も複雑なことはありません。IDEAに助けを求めましょう。彼女は決して拒否しません。コンストラクターを少し複雑にします。デザイナーならできるようになる。フィールドを初期化し、 にそのようなオブジェクトがあるかどうかを確認しallUsers
、そのようなオブジェクトがない場合は、カウンタを増やしてcountId++
すべてのユーザーのリストに追加します。また、フィールドがallUsers
まだ初期化されていない場合は初期化します。同一のオブジェクトを検索しやすくするために、メソッドを再定義しequals()
、再び最愛のIDEAhashCode()
の助けを求めて、フィールド、、、で比較します。さらに、そのようなオブジェクトがリストにあるかどうかを確認する プライベート メソッドを作成しましょう。name
age
sex
hasUser()
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
User user = (User) o;
return age == user.age &&
Objects.equals(name, user.name) &&
sex == user.sex;
}
@Override
public int hashCode() {
return Objects.hash(name, age, sex);
}
最終的にはこんなデザイナーに落ち着きました。
public User(String name, int age, Sex sex) {
if (allUsers == null){
allUsers = new HashMap<>();
}
this.name = name;
this.age = age;
this.sex = sex;
if (!hasUser()){
countId++;
this.id = countId;
allUsers.put(id, this);
}
}
そしてプライベートヘルパーメソッド
private boolean hasUser(){
for (User user : allUsers.values()){
if (user.equals(this) && user.hashCode() == this.hashCode()){
return true;
}
}
return false;
}
そして再定義もしますtoString()
@Override
public String toString() {
return "User{" +
"id=" + id +
", name='" + name + '\'' +
", age=" + age +
", sex=" + sex +
'}';
}
次に、必要なメソッドのロジックを実装します。このロジックは主に静的フィールドで動作するため、オブジェクトには必要ないメソッドも静的にします。
- すべてのユーザーのリストを生成します。
- 性別 (MALE/FEMALE) ごとにユーザーのリストを生成します。
-
一般リスト内のユーザーの数を返し、ユーザーの性別に基づいて数を計算します。
public static int getHowManyUsers(){ return allUsers.size(); } public static int getHowManyUsers(Sex sex){ return getAllUsers(sex).size(); }
-
ユーザーの年齢別に合計金額を計算し、性別も考慮します。このタスクのメソッドを作成しましょう。
public static int getAllAgeUsers(){ int countAge = 0; for (User user : allUsers.values()){ countAge += user.age; } return countAge; } public static int getAllAgeUsers(Sex sex){ int countAge = 0; for (User user : getAllUsers(sex)){ countAge += user.age; } return countAge; }
-
全体と性別の両方の平均年齢を計算します。
public static int getAverageAgeOfAllUsers(){ return getAllAgeUsers() / getHowManyUsers(); } public static int getAverageAgeOfAllUsers(Sex sex){ return getAllAgeUsers(sex) / getHowManyUsers(sex); }
はい、必要なオブジェクトとその動作について説明しました。ここでJUnitに進むことができますが、最初に、 mainで実行した場合に簡単なテストがどのようになるかを示します。
public static void main(String[] args) { new User("Eugene", 35, Sex.MALE); new User("Marina", 34, Sex.FEMALE); new User("Alina", 7, Sex.FEMALE); System.out.println("All users:"); User.getAllUsers().forEach(System.out::println); System.out.println("All users: MALE"); User.getAllUsers(Sex.MALE).forEach(System.out::println); System.out.println("All users: FEMALE"); User.getAllUsers(Sex.FEMALE).forEach(System.out::println); System.out.println("================================================"); System.out.println(" all users: " + User.getHowManyUsers()); System.out.println(" all MALE users: " + User.getHowManyUsers(Sex.MALE)); System.out.println("all FEMALE users: " + User.getHowManyUsers(Sex.FEMALE)); System.out.println("================================================"); System.out.println(" total age of all users: " + User.getAllAgeUsers()); System.out.println(" total age of all MALE users: " + User.getAllAgeUsers(Sex.MALE)); System.out.println("total age of all FEMALE users: " + User.getAllAgeUsers(Sex.FEMALE)); System.out.println("================================================"); System.out.println(" average age of all users: " + User.getAverageAgeOfAllUsers()); System.out.println(" average age of all MALE users: " + User.getAverageAgeOfAllUsers(Sex.MALE)); System.out.println("average age of all FEMALE users: " + User.getAverageAgeOfAllUsers(Sex.FEMALE)); System.out.println("================================================"); }
コンソールへの出力は次のようになります。正常に動作するかどうかを比較してみます。もちろん、すべてを満たせるかどうかはわかりませんが、さらに深く掘り下げて比較ロジックを作成し、計算結果を確認することはできます。
//output Все пользователи: User{id=1, name='Eugene', age=35, sex=MALE} User{id=2, name='Marina', age=34, sex=FEMALE} User{id=3, name='Alina', age=7, sex=FEMALE} Все пользователи: MALE User{id=1, name='Eugene', age=35, sex=MALE} Все пользователи: FEMALE User{id=2, name='Marina', age=34, sex=FEMALE} User{id=3, name='Alina', age=7, sex=FEMALE} ================================================ всех пользователей: 3 всех пользователей MALE: 1 всех пользователей FEMALE: 2 ================================================ общий возраст всех пользователей: 76 общий возраст всех пользователей MALE: 35 общий возраст всех пользователей FEMALE: 41 ================================================ средний возраст всех пользователей: 25 средний возраст всех пользователей MALE: 35 средний возраст всех пользователей FEMALE: 20 ================================================ Process finished with exit code 0
私たちはこの結果に満足していません。メインのテストではJUnitが必要です。
ポイントaとbgetAllUsers()
は、渡されたパラメータに応じて、すべての のリストを返すメソッド、およびリストを返すUser
オーバーロードされたメソッドによって適切に処理できます。getAllUsers(Sex sex)
Sex
public static List<User> getAllUsers(){
return new ArrayList<>(allUsers.values());
}
public static List<User> getAllUsers(Sex sex){
List<User> listAllUsers = new ArrayList<>();
for (User user : allUsers.values()){
if (user.sex == sex){
listAllUsers.add(user);
}
}
return listAllUsers;
}
JUnit をプロジェクトに接続する方法
それをプロジェクトにどのように結び付けるかという問題が生じます。詳しい人のために言っておきますが、これはまったく別の話なので、Mavenを使用するという選択肢はとりません。;) プロジェクト構造を開きます Ctrl + Alt + Shift + S -> ライブラリ -> + (新しいプロジェクト ライブラリ) をクリック -> Maven から選択すると、 このようなウィンドウが表示され、検索バーに「junit:junit:4.12」と入力します。 、見つかるまで待ちます -> OK! -> OK! この結果が得られます 。「OK」をクリックします。おめでとうございます。JUnit がプロジェクトに追加されました。次へ移りましょう。次に、Java クラスのテストを作成する必要があります。クラス名にカーソルを置き、User
Alt + Enter を押し、[テストの作成] を選択します。JUnit4 ライブラリを選択する必要があるウィンドウが表示されます -> テストするメソッドを選択します -> OK この アイデア自体がクラスを作成しますUserTest
。これは、テストでコードをカバーするクラスです。始めましょう:
最初の @Test
最初の@Testメソッドを作成しましょうgetAllUsers()
。これはすべてのユーザーを返すメソッドです。テストは次のようになります。
@Test
public void getAllUsers() {
// create test data
User user = new User("Eugene", 35, Sex.MALE);
User user1 = new User("Marina", 34, Sex.FEMALE);
User user2 = new User("Alina", 7, Sex.FEMALE);
//create an expected list and fill it with the data of our method
List<User> expected = User.getAllUsers();
//create actual list put data in it for comparison
//what we expect the method to return
List<User> actual = new ArrayList<>();
actual.add(user);
actual.add(user1);
actual.add(user2);
//run the test if the list expected and actual are not equal
//the test will fail, read the test results in the console
Assert.assertEquals(expected, actual);
}
ここでは、複数のテスト ユーザーを作成します ->expected
メソッドが返されるユーザーを配置するgetAllUsers()
リストを作成します -> Assert.assertEquals(actual, Expected) メソッドactual
が返されると想定するユーザーを配置するリストを作成しますgetAllUsers()
が使用され、検査された最新のリストをそれに渡します。このメソッドは、提供されたリスト内のオブジェクトをテストし、テスト結果を返します。このメソッドはオブジェクトのすべてのフィールドを比較し、継承がある場合は親のフィールドも比較します。最初のテストを実行しましょう... テストは正常に完了しました。次に、テストを失敗させてみましょう。そのためには、テスト リストの 1 つを変更する必要があります。これを行うには、リストへの 1 人のユーザーの追加をコメント アウトしますactual
。
@Test
public void getAllUsers() {
// create test data
User user = new User("Eugene", 35, Sex.MALE);
User user1 = new User("Marina", 34, Sex.FEMALE);
User user2 = new User("Alina", 7, Sex.FEMALE);
//create an expected list and fill it with the data of our method
List<User> expected = User.getAllUsers();
//create actual list put data in it for comparison
//what we expect the method to return
List<User> actual = new ArrayList<>();
actual.add(user);
actual.add(user1);
//actual.add(user2);
//run the test if the list expected and actual are not equal
//the test will fail, read the test results in the console
Assert.assertEquals(expected, actual);
}
テストを実行すると、次のことがわかります。 ここで、テストが失敗した理由を少し見てみましょう。ここでは、検査されたリストには現在のリストよりも多くのユーザーが含まれていることがわかります。これが失敗の理由です。これをメインで確認できますか?JUnit : main = 1 : 0。完全に異なるオブジェクトが含まれている場合にテストがどのようになるかを見てみましょう。次のように実行してみましょう。
@Test
public void getAllUsers() {
// create test data
User user = new User("Eugene", 35, Sex.MALE);
User user1 = new User("Marina", 34, Sex.FEMALE);
User user2 = new User("Alina", 7, Sex.FEMALE);
//create an expected list and fill it with the data of our method
List<User> expected = User.getAllUsers();
//create actual list put data in it for comparison
//what we expect the method to return
List<User> actual = new ArrayList<>();
actual.add(new User("User1", 1, Sex.MALE));
actual.add(new User("User2", 2, Sex.FEMALE));
actual.add(new User("User3", 3, Sex.MALE));
//run the test if the list expected and actual are not equal
//the test will fail, read the test results in the console
Assert.assertEquals(expected, actual);
}
これはコンソールに表示される内容です。 ここでは、比較されたリストに異なるユーザーがあることがすぐにわかります。また、<クリックして違いを確認> をクリックすることもできます。どのようなデータがあるかを詳細に確認できるウィンドウが表示されます。の問題。IDEA は、相違点があるすべてのフィールドを強調表示します。 main
こんなことが起こり得るでしょうか?- いいえ。JUnit : main = 2 : 0 さて、次に進みましょう。テストでカバーする必要のあるメソッドがまだたくさんあります)。しかし、待ってください。メソッドが返されるかどうかを確認することは悪くありませんgetAllUsers()
。バリデーターによって捕捉されたJavaRushnull
タスクで何を行うか)。やりましょう、3 コペイカの問題です...
@Test
public void getAllUsers_NO_NULL() {
//add check for null
List<User> expected = User.getAllUsers();
Assert.assertNotNull(expected);
}
はい、はい、バリデーターが私たちのクソコードをキャッチする方法はおおよそ次のとおりですnull
次に、このテストを実行して、何が表示されるかを見てみましょう。そしてエラーが表示されますが、どうやって???? ここでどうやってテストエラーが発生するのでしょうか))) そしてここで、コードをテストでカバーすることの最初の成果を得ることができます。覚えているとおり、allUsers
コンストラクターでフィールドを初期化しました。これは、メソッドを呼び出すときにgetAllUsers()
、まだ初期化されていないオブジェクトを参照することを意味します。これを編集して、コンストラクターから初期化を削除し、フィールドの宣言時に実行してみましょう。
private static Map<Integer, User> allUsers = new HashMap<>();
public User(String name, int age, Sex sex) {
this.name = name;
this.age = age;
this.sex = sex;
if (!hasUser()) {
countId++;
this.id = countId;
allUsers.put(id, this);
}
}
テストを実行してみましょう。これですべてがうまくいきました。 main で NPE をキャッチするのは簡単ではないと思います。カウントが JUnit: main = 3: 0 であることに同意していただけると思います。次に、すべてのメソッドをテストでカバーし、どのように表示されるかを見てみましょう。 ...テスト クラスは次のようになります。
package user;
import org.junit.Assert;
import org.junit.Test;
import java.util.ArrayList;
import java.util.List;
import static org.junit.Assert.*;
public class UserTest {
@Test
public void getAllUsers() {
// create test data
User user = new User("Eugene", 35, Sex.MALE);
User user1 = new User("Marina", 34, Sex.FEMALE);
User user2 = new User("Alina", 7, Sex.FEMALE);
//create an expected list and fill it with the data of our method
List<User> expected = User.getAllUsers();
//create actual list put data in it for comparison
//what we expect the method to return
List<User> actual = new ArrayList<>();
actual.add(user);
actual.add(user1);
actual.add(user2);
//run the test if the list expected and actual are not equal
//the test will fail, read the test results in the console
Assert.assertEquals(expected, actual);
}
@Test
public void getAllUsers_NO_NULL() {
//add check for null
List<User> expected = User.getAllUsers();
Assert.assertNotNull(expected);
}
@Test
public void getAllUsers_MALE() {
User user = new User("Eugene", 35, Sex.MALE);
User user1 = new User("Marina", 34, Sex.FEMALE);
User user2 = new User("Alina", 7, Sex.FEMALE);
List<User> expected = User.getAllUsers(Sex.MALE);
List<User> actual = new ArrayList<>();
actual.add(user);
Assert.assertEquals(expected, actual);
}
@Test
public void getAllUsers_MALE_NO_NULL() {
//add check for null
List<User> expected = User.getAllUsers(Sex.MALE);
Assert.assertNotNull(expected);
}
@Test
public void getAllUsers_FEMALE() {
User user = new User("Eugene", 35, Sex.MALE);
User user1 = new User("Marina", 34, Sex.FEMALE);
User user2 = new User("Alina", 7, Sex.FEMALE);
List<User> expected = User.getAllUsers(Sex.FEMALE);
List<User> actual = new ArrayList<>();
actual.add(user1);
actual.add(user2);
Assert.assertEquals(expected, actual);
}
@Test
public void getAllUsers_FEMALE_NO_NULL() {
//add check for null
List<User> expected = User.getAllUsers(Sex.FEMALE);
Assert.assertNotNull(expected);
}
@Test
public void getHowManyUsers() {
User user = new User("Eugene", 35, Sex.MALE);
User user1 = new User("Marina", 34, Sex.FEMALE);
User user2 = new User("Alina", 7, Sex.FEMALE);
int expected = User.getHowManyUsers();
int actual = 3;
Assert.assertEquals(expected, actual);
}
@Test
public void getHowManyUsers_MALE() {
User user = new User("Eugene", 35, Sex.MALE);
User user1 = new User("Marina", 34, Sex.FEMALE);
User user2 = new User("Alina", 7, Sex.FEMALE);
int expected = User.getHowManyUsers(Sex.MALE);
int actual = 1;
Assert.assertEquals(expected, actual);
}
@Test
public void getHowManyUsers_FEMALE() {
User user = new User("Eugene", 35, Sex.MALE);
User user1 = new User("Marina", 34, Sex.FEMALE);
User user2 = new User("Alina", 7, Sex.FEMALE);
int expected = User.getHowManyUsers(Sex.FEMALE);
int actual = 2;
Assert.assertEquals(expected, actual);
}
@Test
public void getAllAgeUsers() {
User user = new User("Eugene", 35, Sex.MALE);
User user1 = new User("Marina", 34, Sex.FEMALE);
User user2 = new User("Alina", 7, Sex.FEMALE);
int expected = User.getAllAgeUsers();
int actual = 35 + 34 + 7;
Assert.assertEquals(expected, actual);
}
@Test
public void getAllAgeUsers_MALE() {
User user = new User("Eugene", 35, Sex.MALE);
User user1 = new User("Marina", 34, Sex.FEMALE);
User user2 = new User("Alina", 7, Sex.FEMALE);
int expected = User.getAllAgeUsers(Sex.MALE);
int actual = 35;
Assert.assertEquals(expected, actual);
}
@Test
public void getAllAgeUsers_FEMALE() {
User user = new User("Eugene", 35, Sex.MALE);
User user1 = new User("Marina", 34, Sex.FEMALE);
User user2 = new User("Alina", 7, Sex.FEMALE);
int expected = User.getAllAgeUsers(Sex.FEMALE);
int actual = 34 + 7;
Assert.assertEquals(expected, actual);
}
}
はい、それは小さくないことが判明しましたが、大規模なプロジェクトで作業する場合はどうなるでしょうか。ここで何を削減できるでしょうか? すべてを評価した後、各テストでテスト データを作成していることがわかりますが、ここでアノテーションが役に立ちます。見てみましょう @Before
- 注釈は、@Before
テストされる各メソッドの前にメソッドが実行されることを示します@Test
。アノテーションを付けたテスト クラスは次のようになります@Before
。
package user;
import org.junit.Assert;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import java.util.ArrayList;
import java.util.List;
import static org.junit.Assert.*;
public class UserTest {
private User user;
private User user1;
private User user2;
@Before
public void setUp() throws Exception {
user = new User("Eugene", 35, Sex.MALE);
user1 = new User("Marina", 34, Sex.FEMALE);
user2 = new User("Alina", 7, Sex.FEMALE);
}
@Test
public void getAllUsers() {
List<User> expected = User.getAllUsers();
List<User> actual = new ArrayList<>();
actual.add(user);
actual.add(user1);
actual.add(user2);
Assert.assertEquals(expected, actual);
}
@Test
public void getAllUsers_NO_NULL() {
List<User> expected = User.getAllUsers();
Assert.assertNotNull(expected);
}
@Test
public void getAllUsers_MALE() {
List<User> expected = User.getAllUsers(Sex.MALE);
List<User> actual = new ArrayList<>();
actual.add(user);
Assert.assertEquals(expected, actual);
}
@Test
public void getAllUsers_MALE_NO_NULL() {
//add check for null
List<User> expected = User.getAllUsers(Sex.MALE);
Assert.assertNotNull(expected);
}
@Test
public void getAllUsers_FEMALE() {
List<User> expected = User.getAllUsers(Sex.FEMALE);
List<User> actual = new ArrayList<>();
actual.add(user1);
actual.add(user2);
Assert.assertEquals(expected, actual);
}
@Test
public void getAllUsers_FEMALE_NO_NULL() {
//add check for null
List<User> expected = User.getAllUsers(Sex.FEMALE);
Assert.assertNotNull(expected);
}
@Test
public void getHowManyUsers() {
int expected = User.getHowManyUsers();
int actual = 3;
Assert.assertEquals(expected, actual);
}
@Test
public void getHowManyUsers_MALE() {
int expected = User.getHowManyUsers(Sex.MALE);
int actual = 1;
Assert.assertEquals(expected, actual);
}
@Test
public void getHowManyUsers_FEMALE() {
int expected = User.getHowManyUsers(Sex.FEMALE);
int actual = 2;
Assert.assertEquals(expected, actual);
}
@Test
public void getAllAgeUsers() {
int expected = User.getAllAgeUsers();
int actual = 35 + 34 + 7;
Assert.assertEquals(expected, actual);
}
@Test
public void getAllAgeUsers_MALE() {
int expected = User.getAllAgeUsers(Sex.MALE);
int actual = 35;
Assert.assertEquals(expected, actual);
}
@Test
public void getAllAgeUsers_FEMALE() {
int expected = User.getAllAgeUsers(Sex.FEMALE);
int actual = 34 + 7;
Assert.assertEquals(expected, actual);
}
}
さて、どうですか、すでに以前よりも楽しくなり、読みやすくなりました ;) 以下は JUnit の注釈のリストです。JUnit を使用すると、間違いなく使いやすくなります。
@Test – определяет что метод method() является тестовым.
@Before – указывает на то, что метод будет выполнятся перед каждым тестируемым методом @Test.
@After – указывает на то что метод будет выполнятся после каждого тестируемого метода @Test
@BeforeClass – указывает на то, что метод будет выполнятся в начале всех тестов,
а точней в момент запуска тестов(перед всеми тестами @Test).
@AfterClass – указывает на то, что метод будет выполнятся после всех тестов.
@Ignore – говорит, что метод будет проигнорирован в момент проведения тестирования.
(expected = Exception.class) – указывает на то, что в данном тестовом методе
вы преднамеренно ожидаете Exception.
(timeout = 100) – указывает, что тестируемый метод не должен занимать больше чем 100 миллисекунд.
チェックのための主なクラスメソッドAssert
:
fail(String) – указывает на то что бы тестовый метод завалился при этом выводя текстовое сообщение.
assertTrue([message], boolean condition) – проверяет, что логическое condition истинно.
assertsEquals([String message], expected, actual) – проверяет, что два значения совпадают.
Примечание: для массивов проверяются ссылки, а не содержание массивов.
assertNull([message], object) – проверяет, что an object является пустым null.
assertNotNull([message], object) – проверяет, что an object не является пустым null.
assertSame([String], expected, actual) – проверяет, что обе переменные относятся к одному an objectу.
assertNotSame([String], expected, actual) – проверяет, что обе переменные относятся к разным an objectм.
これは、Maven に JUnit 4.12 依存関係を追加する方法です。
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
続きはこちら -> JUnit パート II
GO TO FULL VERSION