CyStack logo
  • Sản phẩm & Dịch vụ
  • Giải pháp
  • Bảng giá
  • Công ty
  • Tài liệu
Vi

vi

Trang chủHướng dẫnSử dụng ArgumentCaptor trong Mockito
Java

Sử dụng ArgumentCaptor trong Mockito

CyStack blog 2 phút để đọc
CyStack blog11/09/2025
Locker Avatar

Chris Pham

Technical Writer

Locker logo social
Reading Time: 2 minutes

ArgumentCaptor trong Mockito được dùng để bắt (capture) các tham số được truyền vào những phương thức mock. ArgumentCaptor thường được sử dụng cùng với phương thức Mockito.verify() để lấy ra các tham số đã được truyền vào khi một phương thức nào đó được gọi. Nhờ đó, chúng ta có thể viết thêm các JUnit assertions để kiểm tra kỹ hơn trong test.

Sử dụng ArgumentCaptor trong Mockito

Mockito ArgumentCaptor

Chúng ta có thể tạo một instance ArgumentCaptor cho bất kỳ class nào, sau đó method capture() sẽ được dùng kết hợp với verify(). Cuối cùng, chúng ta có thể lấy các arguments đã được capture bằng các method getValue()getAllValues().

Method getValue() được dùng khi chỉ capture một argument. Nếu verified method được gọi nhiều lần thì getValue() sẽ trả về giá trị mới nhất được capture. Nếu có nhiều arguments được capture, hãy dùng getAllValues() để lấy danh sách các arguments đó.

Ví dụ về Mockito ArgumentCaptor

Giả sử chúng ta có một class được định nghĩa như sau:

class MathUtils {
	public int add(int x, int y) {
		return x + y;
	}

	public boolean isInteger(String s) {
		try {
			Integer.parseInt(s);
		} catch (NumberFormatException e) {
			return false;
		}
		return true;
	}
	
	public long squareLong(long l) {
		return l*l;
	}
}

Chúng ta có thể viết test case và sử dụng ArgumentCaptor như minh họa dưới đây.

@Test
void test() {
	MathUtils mockMathUtils = mock(MathUtils.class);
	when(mockMathUtils.add(1, 1)).thenReturn(2);
	when(mockMathUtils.isInteger(anyString())).thenReturn(true);

	ArgumentCaptor acInteger = ArgumentCaptor.forClass(Integer.class);
	ArgumentCaptor acString = ArgumentCaptor.forClass(String.class);

	assertEquals(2, mockMathUtils.add(1, 1));
	assertTrue(mockMathUtils.isInteger("1"));
	assertTrue(mockMathUtils.isInteger("999"));

	verify(mockMathUtils).add(acInteger.capture(), acInteger.capture());
	List allValues = acInteger.getAllValues();
	assertEquals(List.of(1, 1), allValues);
	
	verify(mockMathUtils, times(2)).isInteger(acString.capture());
	List allStringValues = acString.getAllValues();
	assertEquals(List.of("1", "999"), allStringValues);
}

Mockito @Captor

Chúng ta có thể sử dụng annotation @Captor để tạo argument captor ngay tại cấp độ field. Như vậy, thay vì phải khởi tạo ArgumentCaptor ở cấp độ field như sau:

ArgumentCaptor acLong = ArgumentCaptor.forClass(Long.class);

Chúng ta có thể sử dụng @Captor như sau:

@Captor ArgumentCaptor acLong;

Lưu ý rằng chúng ta phải gọi MockitoAnnotations.initMocks(this); trước các test methods để Mockito framework khởi tạo nó.

Ví dụ về Mockito @Captor

Dưới đây là một ví dụ đơn giản về annotation @Captor.

class MockitoArgumentCaptorExamples {

	@Captor ArgumentCaptor acLong;

	@Test
	void test() {
		MathUtils mockMathUtils = mock(MathUtils.class);
		when(mockMathUtils.squareLong(2L)).thenReturn(4L);
		assertEquals(4L, mockMathUtils.squareLong(2L));
		verify(mockMathUtils).squareLong(acLong.capture());
		assertTrue(2 == acLong.getValue());
	}
}

Bạn có thể xem toàn bộ code và nhiều ví dụ khác về Mockito trong GitHub Repository của chúng tôi.

0 Bình luận

Đăng nhập để thảo luận

Chuyên mục Hướng dẫn

Tổng hợp các bài viết hướng dẫn, nghiên cứu và phân tích chi tiết về kỹ thuật, các xu hướng công nghệ mới nhất dành cho lập trình viên.

Đăng ký nhận bản tin của chúng tôi

Hãy trở thành người nhận được các nội dung hữu ích của CyStack sớm nhất

Xem chính sách của chúng tôi Chính sách bảo mật.

Đăng ký nhận Newsletter

Nhận các nội dung hữu ích mới nhất