Spring MVC和MongoDB:使用Fongo进行单元测试 - 返回Null Pointer Exception

时间:2017-10-03 08:27:31

标签: spring mongodb spring-mvc nullpointerexception

我正在使用 Spring Spring MVC MongoDB 支持的应用程序。

我正在寻找使用 Fongo 保存和阅读文档文件的集成测试。

我的测试夹具类如下:

@ActiveProfiles({ "test"})
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = {SpringMongoConfig.class, MockDatasourceConfig.class})
@WebAppConfiguration
public class FSIntegrationFongoTest extends SpringApplicationContextTest {

  private MockMvc mockMvc;

  @Mock
  private FileService fileService;

  @Mock
  private FileStoreRequest file ;

  @Before
  @Test
  public void setUp() throws IOException {
    //set up FongoDB and collection
    Fongo fongo = new Fongo("FongoTest");
    DB db = fongo.getDB("dbtest");
    DBCollection collection = db.getCollection("filedocuments");

    //test database
    assertNotNull(db);
    assertSame("getDB should be idempotent", db, fongo.getDB("dbtest"));
    assertEquals(Arrays.asList(db), fongo.getUsedDatabases());
    assertEquals(Arrays.asList("dbtest"), fongo.getDatabaseNames());

    //test collection
    assertNotNull(collection);
    assertSame("getCollection should be idempotent", collection, db.getCollection("filedocuments"));

    //import json with collection name filedocuments
    importJSON("filedocuments", "src/test/resources/SampleFiles.json");

    fileService = Mockito.mock(FileServiceImpl.class);
    file = Mockito.mock(FileStoreRequest.class);
  }

  @Test
  public void testInsertFileAndGetIt()throws IOException{
    FileStoreRequest file = new FileStoreRequest();
    file.setId("test1");
    file.setFileName("test1");
    file.setVersionId("1");
    file.setDescription("Test file");
    file.setAlias("Testing");
    file.setContent(MockUtils.getMockFileContent());
    Map<String,String> extraAttributes = new HashMap<>();
    extraAttributes.put("parameter1", "parameter1Name");
    extraAttributes.put("parameter2", "parameter2Name");
    file.setExtraAttributes(extraAttributes);
    fileService.storeFileGeneral(file);
    System.out.println(file);
    assertNotNull(file);
    assertEquals("test1", file.getId());
    assertEquals("test1", file.getFileName());
    //this causes java.lang.NullPointerException
    assertEquals(fileService.getFileById("test1").getFileName(),  file.getFileName());
  }
}

这是我的SpringApplicationContextTest课程:

@ActiveProfiles({ "test"})
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = {SpringMongoConfig.class, MockDatasourceConfig.class,})
public class SpringApplicationContextTest {

  Logger log = LoggerFactory.getLogger(SpringApplicationContextTest.class);

  @Autowired
  private MongoTemplate mongoTemplate;

  public void importJSON(String collection, String file) {
    try {
      for (Object line : FileUtils.readLines(new File(file), "utf8")) {
        log.debug("Import Object to database:" + line);
        mongoTemplate.save(line, collection);
      }
    } catch (IOException e) {
      throw new RuntimeException("Could not import file: " + file, e);
    }
  }

  @Test
  public void testContextInitialized() {
    assertNotNull(mongoTemplate);
  }                                                                                                                     
}

这里是项目 pom.xml 文件:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">

    <properties>
        <spring.version>4.3.3.RELEASE</spring.version>
        <hibernate.version>4.1.0.Final</hibernate.version>
        <spring.data.version>1.9.0.RELEASE</spring.data.version>
        <spring.mongodb.version>1.9.5.RELEASE</spring.mongodb.version>
        <apache.commons.io.version>2.5</apache.commons.io.version>
        <apache.commons.codec.version>1.10</apache.commons.codec.version>
        <apache.commons.fileupload>1.3.2</apache.commons.fileupload>
        <tika.version>1.14</tika.version>
        <swagger.version>2.6.1</swagger.version>
        <jstl.version>1.2</jstl.version>
        <javax.servlet.version>3.1.0</javax.servlet.version>
        <junit.version>4.12</junit.version>
        <hamcrest.version>1.3</hamcrest.version>
        <servlet.api.version>2.5</servlet.api.version>
        <mockito.version>2.2.15</mockito.version>
        <mockwebserver.version>3.8.0</mockwebserver.version>
        <jcl.slf4j.version>1.6.0</jcl.slf4j.version>
        <maven.compiler.source>1.7</maven.compiler.source>
        <maven.compiler.target>1.7</maven.compiler.target>
        <retrofit.version>2.3.0</retrofit.version>
        <okhttp.version>3.8.1</okhttp.version>
        <slf4jVersion>1.6.1</slf4jVersion>
        <nosqlunit-version>0.7.6</nosqlunit-version>
    </properties>

    <dependencies>
        <!-- Spring framework -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-core</artifactId>
            <version>${spring.version}</version>
            <exclusions>
                <exclusion>
                    <groupId>commons-logging</groupId>
                    <artifactId>commons-logging</artifactId>
                </exclusion>
            </exclusions>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>${spring.version}</version>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-beans</artifactId>
            <version>${spring.version}</version>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>${spring.version}</version>
        </dependency>

        <!-- mongodb java driver -->
        <dependency>
            <groupId>org.mongodb</groupId>
            <artifactId>mongo-java-driver</artifactId>
            <version>3.4.2</version>
        </dependency>

        <!-- Spring data mongodb -->
        <dependency>
            <groupId>org.springframework.data</groupId>
            <artifactId>spring-data-mongodb</artifactId>
            <version>${spring.mongodb.version}</version>
        </dependency>

        <dependency>
            <groupId>cglib</groupId>
            <artifactId>cglib</artifactId>
            <version>2.2.2</version>
        </dependency>

        <!-- Spring controllers -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-web</artifactId>
            <version>${spring.version}</version>
        </dependency>

        <!-- Apache commons -->
        <dependency>
            <groupId>commons-codec</groupId>
            <artifactId>commons-codec</artifactId>
            <version>${apache.commons.codec.version}</version>
        </dependency>

        <dependency>
            <groupId>commons-io</groupId>
            <artifactId>commons-io</artifactId>
            <version>${apache.commons.io.version}</version>
        </dependency>

        <dependency>
            <groupId>commons-fileupload</groupId>
            <artifactId>commons-fileupload</artifactId>
            <version>${apache.commons.fileupload}</version>
        </dependency>

        <!-- Apache tika -->
        <dependency>
            <groupId>org.apache.tika</groupId>
            <artifactId>tika-core</artifactId>
            <version>${tika.version}</version>
        </dependency>

        <!-- Swagger 2.0  -->
        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-swagger2</artifactId>
            <version>${swagger.version}</version>
        </dependency>

        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-swagger-ui</artifactId>
            <version>${swagger.version}</version>
        </dependency>

        <!-- Servlet , JSP, JSTL -->
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>jstl</artifactId>
            <version>${jstl.version}</version>
        </dependency>

        <!-- for compile only, your container should have this -->
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>servlet-api</artifactId>
            <version>${servlet.api.version}</version>
            <scope>provided</scope>
        </dependency>

        <!-- Testing Dependencies -->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>${junit.version}</version>
            <scope>test</scope>
            <exclusions>
                <exclusion>
                    <groupId>org.hamcrest</groupId>
                    <artifactId>hamcrest-core</artifactId>
                </exclusion>
            </exclusions>
        </dependency>

        <dependency>
            <groupId>org.hamcrest</groupId>
            <artifactId>hamcrest-library</artifactId>
            <version>${hamcrest.version}</version>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-test</artifactId>
            <version>${spring.version}</version>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>${javax.servlet.version}</version>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>org.mockito</groupId>
            <artifactId>mockito-core</artifactId>
            <version>${mockito.version}</version>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>com.squareup.okhttp3</groupId>
            <artifactId>mockwebserver</artifactId>
            <version>${mockwebserver.version}</version>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>com.jayway.jsonpath</groupId>
            <artifactId>json-path-assert</artifactId>
            <version>2.2.0</version>
            <scope>test</scope>
            <exclusions>
                <exclusion>
                    <groupId>org.hamcrest</groupId>
                    <artifactId>hamcrest-core</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>org.slf4j</groupId>
                    <artifactId>slf4j-api</artifactId>
                </exclusion>
            </exclusions>
        </dependency>

        <dependency>
            <groupId>com.github.fakemongo</groupId>
            <artifactId>fongo</artifactId>
            <version>1.6.8</version>
        </dependency>

        <dependency>
            <groupId>com.lordofthejars</groupId>
            <artifactId>nosqlunit-mongodb</artifactId>
            <version>${nosqlunit-version}</version>
            <scope>test</scope>
        </dependency>

        <!--  Jackson Dependencies -->
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-core</artifactId>
            <version>2.6.3</version>
        </dependency>
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
            <version>2.6.3</version>
        </dependency>
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-annotations</artifactId>
            <version>2.6.3</version>
        </dependency>

        <!--   Retrofit2  -->
        <dependency>
            <groupId>com.squareup.retrofit2</groupId>
            <artifactId>retrofit</artifactId>
            <version>${retrofit.version}</version>
        </dependency>

        <dependency>
            <groupId>com.squareup.retrofit2</groupId>
            <artifactId>converter-gson</artifactId>
            <version>${retrofit.version}</version>
        </dependency>

        <dependency>
            <groupId>com.squareup.retrofit2</groupId>
            <artifactId>converter-jackson</artifactId>
            <version>RELEASE</version>
        </dependency>

        <dependency>
            <groupId>com.squareup.okhttp3</groupId>
            <artifactId>okhttp</artifactId>
            <version>${okhttp.version}</version>
        </dependency>

        <dependency>
            <groupId>org.apache.httpcomponents</groupId>
            <artifactId>httpasyncclient</artifactId>
            <version>4.1.2</version>
        </dependency>

        <dependency>
            <groupId>com.google.code.gson</groupId>
            <artifactId>gson</artifactId>
            <version>2.3</version>
        </dependency>

        <!-- Bridge logging from JCL to SLF4j-->
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>jcl-over-slf4j</artifactId>
            <version>${jcl.slf4j.version}</version>
        </dependency>

        <!-- Binding for NOP, silently discarding all logging. -->
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-nop</artifactId>
            <version>${slf4jVersion}</version>
        </dependency>
    </dependencies>

</project>

运行我的测试夹具时得到NullPointerException

java.lang.NullPointerException
    at com.myproject.fongodb.FSIntegrationFongoTest.testInsertFileAndGetIt(FSIntegrationFongoTest.java:97)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
    at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
    at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
    at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:75)
    at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:86)
    at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:84)
    at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:252)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:94)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
    at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
    at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:191)
    at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
    at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)
    at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:51)
    at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:242)
    at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70) 

有什么问题的任何线索?

1 个答案:

答案 0 :(得分:1)

在测试夹具setUp钩子中,您正在使用模拟对象初始化fileService

fileService = Mockito.mock(FileServiceImpl.class);

然后,您尝试使用模拟对象保存文件:

fileService.storeFileGeneral(file);

由于fileService只是一个模拟,它在#storeFileGeneral调用时不会执行任何操作,也不会像您期望的那样保存任何文件。

稍后,您尝试将持久文件读回到使用正确ID创建的资产,而您获得的只是null引用:

assertEquals(fileService.getFileById("test1").getFileName(),  file.getFileName()); // fileService.getFileById("test1") will return 'null'

简短的回答是检查您的测试夹具,因为它不会反映集成测试,因为您正在测试FileService行为。