Xác minh trong mocking

Nhập môn Kiểm thử trong Java

Maria Milusheva

Senior Software Engineer

Động lực: Không có giá trị trả về

Trong bài trước và bài tập, ta kiểm thử bằng cách assert giá trị trả về.

  • Nhưng nếu không có giá trị trả về thì sao?

  • Nếu giá trị trả về không quan trọng hoặc không hữu ích thì sao?

Ví dụ: lưu vào cơ sở dữ liệu.

Đồ họa một cơ sở dữ liệu với các tệp được lưu vào

Nhập môn Kiểm thử trong Java

Ví dụ: Cơ sở dữ liệu

Cơ sở dữ liệu (Database) - kho số lưu trữ, quản lý và bảo vệ tập dữ liệu có cấu trúc. Có nhiều nhà cung cấp: Logo của một số CSDL phổ biến

  • Máy chủ CSDL bền bỉ, an toàn, tin cậy, và dung lượng gần như không giới hạn

  • CSDL thực tế quá lớn và phức tạp cho unit test (nhưng phù hợp cho integration test)

Nhập môn Kiểm thử trong Java

Ví dụ: Thông điệp log

Giả sử ta xử lý log:

public class MessageProcessor {
    private InfoStore infoStore;  // Will store info log messages here
    private ErrorStore errorStore; // Will store error log messages here

    public void saveMessage(String message) {
        if (message.startsWith("[INFO]")) {
            infoStore.save(message);
        }
        if (message.startsWith("[ERROR]")) {
            errorStore.save(message);
        }
    }
}
Nhập môn Kiểm thử trong Java

InfoStore và ErrorStore

Chỉ cần interface cơ bản để test chạy được:

// Blueprints for InfoStore and ErrorStore
// Mocks don't need the mocked classes to be properly implemented
interface InfoStore {
    void save(String message);
}

interface ErrorStore {
    void save(String message);
}
Nhập môn Kiểm thử trong Java

Mockito verify

Làm sao kiểm thử đã lưu thông điệp mà không tạo CSDL?

Assert mock đã được dùng:

import static org.mockito.Mockito.verify;

Assert mock không được dùng:

import static org.mockito.Mockito.verifyNoInteractions;
Nhập môn Kiểm thử trong Java

Thiết lập kiểm thử

@Test
void process_savesToInfoStore_whenInfoMessage() {
  InfoStore infoStore = mock(InfoStore.class);
  ErrorStore errorStore = mock(ErrorStore.class);
  MessageProcessor messageProcessor = new MessageProcessor(infoStore, errorStore);

String message = "[INFO] Process started."; messageProcessor.saveMessage(message); // Will use either InfoStore or ErrorStore
// Verify which one of the two databases was used verify(infoStore).save(message); verifyNoInteractions(errorStore); }
Nhập môn Kiểm thử trong Java

Thông báo lỗi kiểm thử

Nếu thông điệp tạo ra là:

String message = "[ERROR] Process failed!"

Ta sẽ thấy lỗi kiểm thử như sau:

Wanted but not invoked:
infoStore.save("[ERROR] Process failed!");
Actually, there were zero interactions with this mock.
Nhập môn Kiểm thử trong Java

Mẹo xác minh nâng cao

Ta có thể xác minh chính xác số lần log được gọi:

import static org.mockito.Mockito.times;
List<String> messages = new ArrayList<>(); // Create list and add elements
                messages.add("[INFO] Processing data...");
                messages.add("[INFO] Processing data...");
                messages.add("[INFO] Processing data...");

messageProcessor.saveMessageList(messages); // Save the three messages


verify(infoStore, times(3)).save("[INFO] Processing data...");
Nhập môn Kiểm thử trong Java

Ayo berlatih!

Nhập môn Kiểm thử trong Java

Preparing Video For Download...