Khẳng định các trận đấu regex trong JUnit


81

Ruby's Test::Unitcó một assert_matchesphương pháp hay có thể được sử dụng trong các bài kiểm tra đơn vị để khẳng định rằng regex khớp với một chuỗi.

Có điều gì như thế này trong JUnit không? Hiện tại, tôi làm điều này:

assertEquals(true, actual.matches(expectedRegex));

Câu trả lời:


97

Nếu bạn sử dụng assertThat()với trình so khớp Hamcrest để kiểm tra các khớp regex, thì nếu xác nhận không thành công, bạn sẽ nhận được một thông báo đẹp cho biết mẫu và văn bản thực tế dự kiến. Xác nhận cũng sẽ đọc trôi chảy hơn, ví dụ:

assertThat("FooBarBaz", matchesPattern("^Foo"));

51
Để rõ ràng, không có matchesPatternphương pháp so khớp nào như vậy thực sự tồn tại trong hamcrest AFAICT, bạn phải viết trình so khớp của riêng mình.
pimlottc

7
matchesPatterntồn tại trong jcabi-matchers
yegor256

20
Hamcrest 2.0 hiện đã Matchers.matchesPattern(String)được tích hợp sẵn: github.com/hamcrest/JavaHamcrest/blob/master/hamcrest-library/…
hinneLinks Ngày

4
Permalink cho những gì @hinneLinks đề cập đến: github.com/hamcrest/JavaHamcrest/blob/…
pioto

54

Không có sự lựa chọn nào khác mà tôi biết. Chỉ cần kiểm tra javadoc khẳng định để chắc chắn. Tuy nhiên, chỉ là một chút thay đổi nhỏ:

assertTrue(actual.matches(expectedRegex));

CHỈNH SỬA: Tôi đã sử dụng trình khớp Hamcrest kể từ câu trả lời của pholser, hãy kiểm tra điều đó!


1
À vâng, assertTrue()chắc chắn là đẹp hơn. Tôi đổ lỗi cho tính năng tự động hoàn thành của Eclipse vì tôi không biết về điều đó. ;)
Josh Glover

4
assertTruekhông thể cung cấp cho bạn như chi tiết nhiều càng tốt assertEqualshoặc assertThatkhi một thử nghiệm thất bại
Mike Valenty

1
@Michael Chắc chắn nó có thể. assertTrue("Expected string matching '" +expectedRegex+ "'. Got: "+actual, actual.matches(expectedRegex));. Tuy nhiên, nó không đẹp bằng Hamcrest.
MikeFHay

@MikeValenty Nếu bạn chỉ so sánh một giá trị với is(true), thì assertThatkhông cung cấp cho bạn bất kỳ chi tiết nào hơn assertTruehiện tại. Để nhận được thông báo lỗi thích hợp, bạn cần một trình đối sánh khác (hoặc bạn tạo thông báo theo cách thủ công như @MikeFHay đề xuất).
ThrawnCA

20

Bạn có thể sử dụng Hamcrest, nhưng bạn phải viết trình kết hợp của riêng mình:

public class RegexMatcher extends TypeSafeMatcher<String> {

    private final String regex;

    public RegexMatcher(final String regex) {
        this.regex = regex;
    }

    @Override
    public void describeTo(final Description description) {
        description.appendText("matches regex=`" + regex + "`");
    }

    @Override
    public boolean matchesSafely(final String string) {
        return string.matches(regex);
    }


    public static RegexMatcher matchesRegex(final String regex) {
        return new RegexMatcher(regex);
    }
}

sử dụng

import org.junit.Assert;


Assert.assertThat("test", RegexMatcher.matchesRegex(".*est");

18

Bạn có thể sử dụng Hamcrest và jcabi-matchers :

import static com.jcabi.matchers.RegexMatchers.matchesPattern;
import static org.junit.Assert.assertThat;
assertThat("test", matchesPattern("[a-z]+"));

Thêm chi tiết tại đây: Matchers Hamcrest biểu hiện thông thường .

Bạn sẽ cần hai phụ thuộc này trong classpath:

<dependency>
  <groupId>org.hamcrest</groupId>
  <artifactId>hamcrest-core</artifactId>
  <version>1.3</version>
  <scope>test</scope>
</dependency>
<dependency>
  <groupId>com.jcabi</groupId>
  <artifactId>jcabi-matchers</artifactId>
  <version>1.3</version>
  <scope>test</scope>
</dependency>

Tôi đã phát hiện ra rằng sự phụ thuộc hamcrest lõi là không cần thiết
JohnP2

4

Vì tôi cũng đang tìm kiếm chức năng này, tôi đã bắt đầu một dự án trên GitHub có tên là regex-tester . Đó là một thư viện giúp dễ dàng kiểm tra các biểu thức chính quy trong Java (hiện chỉ hoạt động với JUnit).

Thư viện hiện rất hạn chế, nhưng nó có trình khớp Hamcrest hoạt động như thế này

assertThat("test", doesMatchRegex("tes.+"));
assertThat("test", doesNotMatchRegex("tex.+"));

Tìm hiểu thêm về cách sử dụng regex-tester tại đây .


4

Một trình so khớp tương tự như cách triển khai của Ralph đã được thêm vào thư viện trình khớp Java Hamcrest chính thức. Thật không may, nó chưa có sẵn trong một gói phát hành. Mặc dù vậy, lớp học có trên GitHub nếu bạn muốn xem.


3

Có trình đối sánh tương ứng trong Hamcrest: org.hamcrest.Matchers.matchesPattern (Chuỗi regex) .

Khi quá trình phát triển của Hamcrest bị đình trệ, bạn không thể sử dụng v1.3 mới nhất có sẵn:

testCompile("org.hamcrest:hamcrest-library:1.3")

Thay vào đó, bạn cần sử dụng chuỗi nhà phát triển mới (nhưng vẫn còn ngày tháng 1 năm 2015 ):

testCompile("org.hamcrest:java-hamcrest:2.0.0.0")

hoặc thậm chí tốt hơn:

configurations {
    testCompile.exclude group: "org.hamcrest", module: "hamcrest-core"
    testCompile.exclude group: "org.hamcrest", module: "hamcrest-library"
}
dependencies {
    testCompile("org.hamcrest:hamcrest-junit:2.0.0.0")
}

Trong thử nghiệm:

Assert.assertThat("123456", Matchers.matchesPattern("^[0-9]+$"));

Tôi gặp lỗi: Trùng lặp lớp org.hamcrest.BaseDescription được tìm thấy trong các mô-đun jetified-hamcrest-core-1.3.jar (org.hamcrest: hamcrest-core: 1.3) và jetified-java-hamcrest-2.0.0.0.jar (org.hamcrest : java-hamcrest: 2.0.0.0)
a_subscriber

2

một thay thế khác bằng cách sử dụng khẳng địnhj. cách tiếp cận này rất hay vì nó cho phép bạn truyền trực tiếp đối tượng mẫu.

import static org.assertj.core.api.Assertions.assertThat;
assertThat("my\nmultiline\nstring").matches(Pattern.compile("(?s)my.*string", Pattern.MULTILINE));

1


nó không phải là JUnit nhưng đây là một cách khác với fest-khẳng định:

assertThat(myTestedValue).as("your value is so so bad").matches(expectedRegex);
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.