如何使用字符串来描述Java中的测试用例?

时间:2015-10-31 03:23:41

标签: java testing junit

使用JUnit,我的测试用例的描述通常在方法名称中,如:

@Test
public void should_return_6_if_distance_is_2km() {
}

@Test
public void shouldReturn6IfDistanceIs2km() {
}

哪个不太可读。

但是使用其他语言的测试框架,比如javascript或scala,我可以使用:

describe("Taximeter") {
    it("should return 6 if the distance is 2km") {
        ...
    }
}

使用普通字符串更易读。

是否可以在Java中执行此操作?

7 个答案:

答案 0 :(得分:4)

使用好的断言框架,例如HamcrestAssertJTruth,至少会自动产生更好的错误消息。当然,断言本身比仅使用assertTrueassertEquals等更具可读性。

例如,AssertJ:

assertThat( myVar ).describedAs( "myVar" ).isEqualTo( 6 );

这将导致错误消息(如果myVar!= 6)包含名称" myVar",期望值和实际值。

答案 1 :(得分:3)

JUnit中的断言方法允许您执行类似的操作。你可以这样做:

assertTrue("Should return 6 if the distance is 2km but returned " + myvar, myvar == 6);

这允许您的代码可读,但只有在未满足预期条件时才返回消息。

答案 2 :(得分:3)

Spectrum非常接近我的要求:

@RunWith(Spectrum.class)
public class ExampleSpec {{

    describe("A spec", () -> {

        final int foo = 1;

        it("is just a code block with a run() method", new Block() {
            @Override
            public void run() throws Throwable {
                assertEquals(1, foo);
            }
        });

        it("can also be a lambda function, which is a lot prettier", () -> {
            assertEquals(1, foo);
        });

        it("can use any assertion library you like", () -> {
            org.junit.Assert.assertEquals(1, foo);
            org.hamcrest.MatcherAssert.assertThat(true, is(true));
        });

        describe("nested inside a second describe", () -> {

            final int bar = 1;

            it("can reference both scopes as needed", () -> {
                assertThat(bar, is(equalTo(foo)));
            });

        });

        it("can have `it`s and `describe`s in any order", () -> {
            assertThat(foo, is(1));
        });

    });
}

答案 3 :(得分:1)

不确定Scala-Part,这只是一个描述或可运行的Testcode吗?

如果说明: 对于可读但可自动执行的Testcase-Descriptions,请查看 黄瓜(https://cucumber.io)或jBehave(http://jbehave.org

如果可运行代码: 要尝试使Testcase本身的代码更具可读性,可以选择使用hamcrest(https://code.google.com/p/hamcrest/wiki/Tutorial)。

答案 4 :(得分:0)

您必须为此编写自己的Runner并将其与@RunWith一起使用。

答案 5 :(得分:0)

我长期以来一直在想同样的事情。我找到的最接近"描述" - "它"组织测试的方法是NestedRunner。 Check it out here

它不一样,有一些限制,但绝对是一种改进。

刚看到发布的链接OP - Spectrum甚至更好!我肯定会尽快尝试。感谢分享:)

答案 6 :(得分:0)

使用Mockito框架编写的单元测试非常易读。文档承诺能够“编写漂亮的测试”,这些测试“更具可读性”并“产生干净的验证错误。”请亲自看看:

import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.runners.MockitoJUnitRunner;

import static org.junit.Assert.assertThat;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import static org.mockito.Mockito.eq;

@RunWith(MockitoJUnitRunner.class)
public class UserServiceTest {

    @Mock
    private UserRepository userRepositoryMock;

    @InjectMocks
    private UserService userService = new UserService();

    @Test
    public void testLoadUserByUsername() {
        // Expected objects
        User demoUser = new User("user", "demo", "ROLE_USER");

        // Mockito expectations
        when(userRepositoryMock.findByUsername("user")).thenReturn(demoUser);

        // Execute the method being tested
        User userDetails = userService.loadUserByUsername("user");

        // Validation
        assertThat(userDetails.getUsername(), eq("user"));
        verify(userRepositoryMock).findByUsername("user");
    }
}

要使Maock可以使用Mockito,应使用以下依赖项:

<dependency>
    <groupId>org.mockito</groupId>
    <artifactId>mockito-core</artifactId>
    <version>2.8.47</version>
    <scope>test</scope>
</dependency>

要让Gradle使用Mockito,应使用以下依赖项:

dependencies { testCompile "org.mockito:mockito-core:2.+" }