jjzjj

spring - 服务单元测试类中的 GridFsTemplate NullPointerException(技术堆栈 : Spring Data/Spring Boot/Micro Service/Mongodb )

coder 2023-11-05 原文

我正在开发一个 spring boot 应用程序。 服务方法使用在服务中 Autowiring 的 GridFsTemplate 将 PDF 上传到 mongodb 存储库。 此文件上传服务方法通过 postman 休息客户端按预期工作。 但是,当我尝试运行单元测试时;调用相同的服务方法,SpringData GridFsTemplate 未初始化(在 MongoDB 中,您可以使用 GridFS 存储二进制文件)。这导致 org.springframework.data.mongodb.gridfs.GridFsTemplate.store(...) 抛出 NullPointerException。 拜托,你能帮忙吗,我已经被困在这几天了。

下面是我的服务实现:

@Service
public final class UploadServiceImpl implements UploadService {

    @Autowired
    private SequenceRepository sequenceDao;

    @Autowired (required = true)
    private GridFsTemplate gridFsTemplate;

    @Override
    public Long uploadFile(Invoice uploadedInvoice) {

        ByteArrayInputStream byteArrayInputStream = null;

        if (checkContentType(invoiceInfo.getContentType())) {

            invoiceInfo.setPaymentID(sequenceDao.getNextSequenceId(INVOICE_UPLOAD_SEQ_KEY));
            byteArrayInputStream = new ByteArrayInputStream(uploadedInvoice.getFileContent());

//Error thrown is java.lang.NullPointerException: null, where     gridFsTemplate is null and basically autowire does not work when test is     run.

                GridFSFile gridFSUploadedFile=     gridFsTemplate.store(byteArrayInputStream, invoiceInfo.getFileName(),     invoiceInfo.getContentType(), invoiceInfo);
                return  1l;

        } else {
            return 2l;
        }
    }
### 下面是我的服务单元测试类
@RunWith(MockitoJUnitRunner.class)
@ContextConfiguration
public class UploadServiceTest {

    @Mock
    private SequenceRepository sequenceRepositoryMock;

    @Autowired
    private GridFsTemplate gridFsTemplateMock;

    @Mock
    private Invoice invoiceMock;

    @InjectMocks
    private static UploadService uploadService = new UploadServiceImpl();

    DBObject fileMetaData = null;

    DB db = null;
    Jongo jongo = null;

 @Before
    public void setUp() throws Exception {
        db = new Fongo("Test").getDB("Database");
        jongo = new Jongo(db);
    }

@Test
    public void testUploadFile() {

        //test 1
        Long mockPaymentNo = new Long(1);
        Mockito.when(sequenceRepositoryMock.getNextSequenceId(INVOICE_SEQUENCE)).thenReturn(mockPaymentNo);
        assertEquals(mockPaymentNo, (Long) sequenceRepositoryMock.getNextSequenceId(INVOICE_SEQUENCE));

        //test 2

        Invoice dummyInvoice = getDummyInvoice();
        InvoiceInfo dummyInvoiceInfo = dummyInvoice.getInvoiceInfo();

        MongoCollection invoicesCollection = jongo.getCollection("invoices");

        assertNotNull(invoicesCollection.save(dummyInvoiceInfo));
        assertEquals(1, invoicesCollection.save(dummyInvoiceInfo).getN());

        System.out.println("TEST 2 >>>>>>>>>>>>>>>>>> "+ uploadService);


        //test 3 : The following line is the cause of the exception, the service method is called but the GridFsTemplate is not initialized when the test is run. But it works when the endpoint is invoked via postman

        uploadService.uploadFile(dummyInvoice);

        System.out.println("TEST 3 >>>>>>>>>>>>>>>>>> ");

    }
}

最佳答案

问题是因为您使用@InjectMocks 来 Autowiring 您的UploadService。 并且 UploadService Autowiring 另外两个 bean SequenceRepository 和 GridFsTemplate。

If you’re doing TDD or not (and we are able to change the test first) – clients of this code don’t know about an additional dependency, because it’s completely hidden

Javadoc 声明:

Mockito will try to inject mocks only either by constructor injection, setter injection, or property injection in order and as described below. If any of the following strategy fail, then Mockito won’t report failure; i.e. you will have to provide dependencies yourself.

解决方案是使用 UploadServiceImpl 构造函数来 Autowiring bean:

@Service
public final class UploadServiceImpl implements UploadService {

    private final SequenceRepository sequenceDao;
    private final GridFsTemplate gridFsTemplate;
    private final PlannerClient plannerClient;

    @Autowired
    public PlannerServiceImpl(PlannerClient plannerClient, GridFsTemplate gridFsTemplate, SequenceRepository sequenceDao) {
        this.plannerClient = plannerClient;
    }
...

}

当需要更多的依赖时,它们是清晰可见的,因为它们是在构造函数中初始化的

更详细:

https://tedvinke.wordpress.com/2014/02/13/mockito-why-you-should-not-use-injectmocks-annotation-to-autowire-fields/

关于spring - 服务单元测试类中的 GridFsTemplate NullPointerException(技术堆栈 : Spring Data/Spring Boot/Micro Service/Mongodb ),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38014699/

有关spring - 服务单元测试类中的 GridFsTemplate NullPointerException(技术堆栈 : Spring Data/Spring Boot/Micro Service/Mongodb )的更多相关文章

  1. ruby - 使用 ruby​​ 和 savon 的 SOAP 服务 - 2

    我正在尝试使用ruby​​和Savon来使用网络服务。测试服务为http://www.webservicex.net/WS/WSDetails.aspx?WSID=9&CATID=2require'rubygems'require'savon'client=Savon::Client.new"http://www.webservicex.net/stockquote.asmx?WSDL"client.get_quotedo|soap|soap.body={:symbol=>"AAPL"}end返回SOAP异常。检查soap信封,在我看来soap请求没有正确的命名空间。任何人都可以建议我

  2. ruby - 具有身份验证的私有(private) Ruby Gem 服务器 - 2

    我想安装一个带有一些身份验证的私有(private)Rubygem服务器。我希望能够使用公共(public)Ubuntu服务器托管内部gem。我读到了http://docs.rubygems.org/read/chapter/18.但是那个没有身份验证-如我所见。然后我读到了https://github.com/cwninja/geminabox.但是当我使用基本身份验证(他们在他们的Wiki中有)时,它会提示从我的服务器获取源。所以。如何制作带有身份验证的私有(private)Rubygem服务器?这是不可能的吗?谢谢。编辑:Geminabox问题。我尝试“捆绑”以安装新的gem..

  3. ruby-on-rails - 带 Spring 锁的 Rails 4 控制台 - 2

    我正在使用Ruby2.1.1和Rails4.1.0.rc1。当执行railsc时,它被锁定了。使用Ctrl-C停止,我得到以下错误日志:~/.rvm/gems/ruby-2.1.1/gems/spring-1.1.2/lib/spring/client/run.rb:47:in`gets':Interruptfrom~/.rvm/gems/ruby-2.1.1/gems/spring-1.1.2/lib/spring/client/run.rb:47:in`verify_server_version'from~/.rvm/gems/ruby-2.1.1/gems/spring-1.1.

  4. ruby-on-rails - 启动 Rails 服务器时 ImageMagick 的警告 - 2

    最近,当我启动我的Rails服务器时,我收到了一长串警告。虽然它不影响我的应用程序,但我想知道如何解决这些警告。我的估计是imagemagick以某种方式被调用了两次?当我在警告前后检查我的git日志时。我想知道如何解决这个问题。-bcrypt-ruby(3.1.2)-better_errors(1.0.1)+bcrypt(3.1.7)+bcrypt-ruby(3.1.5)-bcrypt(>=3.1.3)+better_errors(1.1.0)bcrypt和imagemagick有关系吗?/Users/rbchris/.rbenv/versions/2.0.0-p247/lib/ru

  5. ruby-on-rails - s3_direct_upload 在生产服务器中不工作 - 2

    在Rails4.0.2中,我使用s3_direct_upload和aws-sdkgems直接为s3存储桶上传文件。在开发环境中它工作正常,但在生产环境中它会抛出如下错误,ActionView::Template::Error(noimplicitconversionofnilintoString)在View中,create_cv_url,:id=>"s3_uploader",:key=>"cv_uploads/{unique_id}/${filename}",:key_starts_with=>"cv_uploads/",:callback_param=>"cv[direct_uplo

  6. ruby - 用 Ruby 编写一个简单的网络服务器 - 2

    我想在Ruby中创建一个用于开发目的的极其简单的Web服务器(不,不想使用现成的解决方案)。代码如下:#!/usr/bin/rubyrequire'socket'server=TCPServer.new('127.0.0.1',8080)whileconnection=server.acceptheaders=[]length=0whileline=connection.getsheaders想法是从命令行运行这个脚本,提供另一个脚本,它将在其标准输入上获取请求,并在其标准输出上返回完整的响应。到目前为止一切顺利,但事实证明这真的很脆弱,因为它在第二个请求上中断并出现错误:/usr/b

  7. ruby-on-rails - 在 Rails 中调试生产服务器 - 2

    您如何在Rails中的实时服务器上进行有效调试,无论是在测试版/生产服务器上?我试过直接在服务器上修改文件,然后重启应用,但是修改好像没有生效,或者需要很长时间(缓存?)我也试过在本地做“脚本/服务器生产”,但是那很慢另一种选择是编码和部署,但效率很低。有人对他们如何有效地做到这一点有任何见解吗? 最佳答案 我会回答你的问题,即使我不同意这种热修补服务器代码的方式:)首先,你真的确定你已经重启了服务器吗?您可以通过跟踪日志文件来检查它。您更改的代码显示的View可能会被缓存。缓存页面位于tmp/cache文件夹下。您可以尝试手动删除

  8. ruby-on-rails - Prawn - 表格单元格内的链接 - 2

    我正在尝试用Prawn生成PDF。在我的PDF模板中,我有带单元格的表格。在其中一个单元格中,我有一个电子邮件地址:cell_email=pdf.make_cell(:content=>booking.user_email,:border_width=>0)我想让电子邮件链接到“mailto”链接。我知道我可以这样链接:pdf.formatted_text([{:text=>booking.user_email,:link=>"mailto:#{booking.user_email}"}])但是将这两行组合起来(将格式化文本作为内容)不起作用:cell_email=pdf.make_c

  9. spring.profiles.active和spring.profiles.include的使用及区别说明 - 2

    转自:spring.profiles.active和spring.profiles.include的使用及区别说明下文笔者讲述spring.profiles.active和spring.profiles.include的区别简介说明,如下所示我们都知道,在日常开发中,开发|测试|生产环境都拥有不同的配置信息如:jdbc地址、ip、端口等此时为了避免每次都修改全部信息,我们则可以采用以上的属性处理此类异常spring.profiles.active属性例:配置文件,可使用以下方式定义application-${profile}.properties开发环境配置文件:application-dev

  10. ruby - 我的 Ruby IRC 机器人没有连接到 IRC 服务器。我究竟做错了什么? - 2

    require"socket"server="irc.rizon.net"port="6667"nick="RubyIRCBot"channel="#0x40"s=TCPSocket.open(server,port)s.print("USERTesting",0)s.print("NICK#{nick}",0)s.print("JOIN#{channel}",0)这个IRC机器人没有连接到IRC服务器,我做错了什么? 最佳答案 失败并显示此消息::irc.shakeababy.net461*USER:Notenoughparame

随机推荐