Teste de unidade do Cloud Storage (2ª geração)

Exemplo de teste de unidade para uma função acionada pelo Cloud Storage em execução no Cloud Functions (2nd gen).

Exemplo de código

Para autenticar nas funções do Cloud Run, configure o Application Default Credentials. Para mais informações, consulte Configurar a autenticação para um ambiente de desenvolvimento local.

using CloudNative.CloudEvents;
using Google.Cloud.Functions.Testing;
using Google.Events;
using Google.Events.Protobuf.Cloud.Storage.V1;
using Microsoft.Extensions.Logging;
using System;
using System.Threading;
using System.Threading.Tasks;
using Xunit;

namespace HelloWorld.Tests;

public class HelloGcsUnitTest
{
    [Fact]
    public async Task FileNameIsLogged()
    {
        // Prepare the inputs
        var data = new StorageObjectData { Name = "new-file.txt" };
        var cloudEvent = new CloudEvent
        {
            Type = StorageObjectData.FinalizedCloudEventType,
            Source = new Uri("//storage.googleapis.com", UriKind.RelativeOrAbsolute),
            Id = "1234",
            Data = data
        };
        var logger = new MemoryLogger<HelloGcs.Function>();

        // Execute the function
        var function = new HelloGcs.Function(logger);
        await function.HandleAsync(cloudEvent, data, CancellationToken.None);

        // Check the log results - just the entry starting with "File:".
        var logEntry = Assert.Single(logger.ListLogEntries(), entry => entry.Message.StartsWith("File:"));
        Assert.Equal("File: new-file.txt", logEntry.Message);
        Assert.Equal(LogLevel.Information, logEntry.Level);
    }
}

Para autenticar nas funções do Cloud Run, configure o Application Default Credentials. Para mais informações, consulte Configurar a autenticação para um ambiente de desenvolvimento local.


package helloworld

import (
	"context"
	"io"
	"log"
	"os"
	"strings"
	"testing"
	"time"

	"github.com/cloudevents/sdk-go/v2/event"
	"github.com/googleapis/google-cloudevents-go/cloud/storagedata"
	"google.golang.org/protobuf/encoding/protojson"
	"google.golang.org/protobuf/types/known/timestamppb"
)

func TestHelloStorage(t *testing.T) {
	r, w, _ := os.Pipe()
	log.SetOutput(w)
	originalFlags := log.Flags()
	log.SetFlags(log.Flags() &^ (log.Ldate | log.Ltime))

	d := &storagedata.StorageObjectData{
		Name:        "hello_gcs.txt",
		TimeCreated: timestamppb.New(time.Now()),
	}

	jsonData, err := protojson.Marshal(d)
	if err != nil {
		t.Fatalf("protojson.Marshal: %v", err)
	}

	e := event.New()
	e.SetDataContentType("application/json")
	e.SetData(e.DataContentType(), jsonData)

	helloStorage(context.Background(), e)

	w.Close()
	log.SetOutput(os.Stderr)
	log.SetFlags(originalFlags)

	out, err := io.ReadAll(r)
	if err != nil {
		t.Fatalf("ReadAll: %v", err)
	}
	got := string(out)
	if want := d.Name; strings.Contains(want, got) {
		t.Errorf("HelloStorage = %q, want to contain %q", got, want)
	}
	if want := d.TimeCreated.String(); strings.Contains(want, got) {
		t.Errorf("HelloStorage = %q, want to contain %q", got, want)
	}
}

Para autenticar nas funções do Cloud Run, configure o Application Default Credentials. Para mais informações, consulte Configurar a autenticação para um ambiente de desenvolvimento local.


import static com.google.common.truth.Truth.assertThat;

import com.google.common.testing.TestLogHandler;
import com.google.events.cloud.storage.v1.StorageObjectData;
import com.google.protobuf.InvalidProtocolBufferException;
import com.google.protobuf.Timestamp;
import com.google.protobuf.util.JsonFormat;
import io.cloudevents.CloudEvent;
import io.cloudevents.core.builder.CloudEventBuilder;
import java.net.URI;
import java.util.logging.Logger;
import org.junit.After;
import org.junit.BeforeClass;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;

/** Unit tests for main.java.com.example.functions.helloworld.HelloGcs. */
@RunWith(JUnit4.class)
public class HelloGcsTest {
  private static final TestLogHandler LOG_HANDLER = new TestLogHandler();
  private static final Logger logger = Logger.getLogger(HelloGcs.class.getName());

  @BeforeClass
  public static void beforeClass() throws Exception {
    logger.addHandler(LOG_HANDLER);
  }

  @After
  public void afterTest() {
    LOG_HANDLER.clear();
  }

  @Test
  public void helloGcs_shouldPrintFileName() throws InvalidProtocolBufferException {
    // Create event data
    String file = "foo.txt";
    String bucket = "gs://test-bucket";

    // Get the current time in milliseconds
    long millis = System.currentTimeMillis();

    // Create a Timestamp object
    Timestamp timestamp = Timestamp.newBuilder()
        .setSeconds(millis / 1000)
        .setNanos((int) ((millis % 1000) * 1000000))
        .build();

    StorageObjectData.Builder dataBuilder = StorageObjectData.newBuilder()
        .setName(file)
        .setBucket(bucket)
        .setMetageneration(10)
        .setTimeCreated(timestamp)
        .setUpdated(timestamp);

    String jsonData = JsonFormat.printer().print(dataBuilder);

    // Construct a CloudEvent
    CloudEvent event = CloudEventBuilder.v1()
        .withId("0")
        .withType("google.storage.object.finalize")
        .withSource(URI.create("https://example.com"))
        .withData("application/json", jsonData.getBytes())
        .build();

    new HelloGcs().accept(event);

    String actualBucket = LOG_HANDLER.getStoredLogRecords().get(2).getMessage();
    String actualFile = LOG_HANDLER.getStoredLogRecords().get(3).getMessage();
    assertThat(actualFile).contains("File: " + file);
    assertThat(actualBucket).contains("Bucket: " + bucket);
  }

  @Test
  public void helloGcs_shouldPrintNotifyIfDataIsNull() throws InvalidProtocolBufferException {
    // Construct a CloudEvent
    CloudEvent event = CloudEventBuilder.v1()
        .withId("0")
        .withType("google.storage.object.finalize")
        .withSource(URI.create("https://example.com"))
        .build();

    new HelloGcs().accept(event);

    String logMessage = LOG_HANDLER.getStoredLogRecords().get(2).getMessage();
    assertThat(logMessage).isEqualTo("No data found in cloud event payload!");
  }
}

Para autenticar nas funções do Cloud Run, configure o Application Default Credentials. Para mais informações, consulte Configurar a autenticação para um ambiente de desenvolvimento local.

const {getFunction} = require('@google-cloud/functions-framework/testing');

describe('functions_cloudevent_storage', () => {
  const assert = require('assert');
  const sinon = require('sinon');
  require('..');

  const stubConsole = function () {
    sinon.stub(console, 'error');
    sinon.stub(console, 'log');
  };

  const restoreConsole = function () {
    console.log.restore();
    console.error.restore();
  };

  beforeEach(stubConsole);
  afterEach(restoreConsole);

  it('helloGCS: should print out event', () => {
    const event = {
      id: '1234',
      type: 'mock-gcs-event',
      data: {
        bucket: 'my-bucket',
        name: 'my-file.txt',
      },
    };

    // Call tested function and verify its behavior
    const helloGCS = getFunction('helloGCS');
    helloGCS(event);

    assert(console.log.calledWith('Event ID: 1234'));
    assert(console.log.calledWith('Event Type: mock-gcs-event'));
    assert(console.log.calledWith('Bucket: my-bucket'));
    assert(console.log.calledWith('File: my-file.txt'));
  });
});

Para autenticar nas funções do Cloud Run, configure o Application Default Credentials. Para mais informações, consulte Configurar a autenticação para um ambiente de desenvolvimento local.


namespace Google\Cloud\Samples\Functions\HelloworldStorage\Test;

use CloudEvents\V1\CloudEventImmutable;
use CloudEvents\V1\CloudEventInterface;

use PHPUnit\Framework\TestCase;

/**
 * Class SampleUnitTest.
 *
 * Unit test for 'Helloworld Storage' Cloud Function.
 */
class SampleUnitTest extends TestCase
{
    /**
     * Include the Cloud Function code before running any tests.
     *
     * @see https://phpunit.readthedocs.io/en/latest/fixtures.html
     */
    public static function setUpBeforeClass(): void
    {
        require_once __DIR__ . '/index.php';
    }

    public function dataProvider()
    {
        return [
            [
                'cloudevent' => new CloudEventImmutable(
                    uniqId(), // id
                    'storage.googleapis.com', // source
                    'google.cloud.storage.object.v1.finalized', // type
                    [
                        'bucket' => 'some-bucket',
                        'metageneration' => '1',
                        'name' => 'folder/friendly.txt',
                        'timeCreated' => '2020-04-23T07:38:57.230Z',
                        'updated' => '2020-04-23T07:38:57.230Z',
                    ] // data
                ),
                'statusCode' => '200',
            ],
        ];
    }

    /**
     * @dataProvider dataProvider
     */
    public function testFunction(CloudEventInterface $cloudevent): void
    {
        // Capture function output by overriding the function's logging behavior.
        // The 'LOGGER_OUTPUT' environment variable must be used in your function:
        //
        // $log = fopen(getenv('LOGGER_OUTPUT') ?: 'php://stderr', 'wb');
        // fwrite($log, 'Log Entry');
        putenv('LOGGER_OUTPUT=php://output');
        helloGCS($cloudevent);
        // Provided by PHPUnit\Framework\TestCase.
        $actual = $this->getActualOutput();

        // Test output includes the properties provided in the CloudEvent.
        foreach ($cloudevent->getData() as $property => $value) {
            $this->assertStringContainsString($value, $actual);
        }
        $this->assertStringContainsString($cloudevent->getId(), $actual);
        $this->assertStringContainsString($cloudevent->getType(), $actual);
    }
}

Para autenticar nas funções do Cloud Run, configure o Application Default Credentials. Para mais informações, consulte Configurar a autenticação para um ambiente de desenvolvimento local.


from cloudevents.http import CloudEvent
import pytest

import main


def test_functions_eventsource_storage(capsys: pytest.LogCaptureFixture) -> None:
    attributes = {
        "id": "5e9f24a",
        "type": "google.cloud.storage.object.v1.finalized",
        "source": "sourceUrlHere",
    }

    data = {
        "bucket": "test_bucket_for_storage",
        "name": "new_blob_uploaded",
        "generation": 1,
        "metageneration": 1,
        "timeCreated": "2021-10-10 00:00:00.000000Z",
        "updated": "2021-11-11 00:00:00.000000Z",
    }

    event = CloudEvent(attributes, data)

    (
        event_id,
        event_type,
        bucket,
        name,
        metageneration,
        timeCreated,
        updated,
    ) = main.hello_gcs(event)

    out, _ = capsys.readouterr()
    assert "5e9f24a" in event_id
    assert "google.cloud.storage.object.v1.finalized" in event_type
    assert "test_bucket_for_storage" in bucket
    assert "new_blob_uploaded" in name
    assert metageneration == 1
    assert "2021-10-10 00:00:00.000000Z" in timeCreated
    assert "2021-11-11 00:00:00.000000Z" in updated

A seguir

Para pesquisar e filtrar exemplos de código de outros Google Cloud produtos, consulte a pesquisa de exemplos de código doGoogle Cloud .