GoogleCloudVision C# - 如何单元测试服务

发布于 2025-02-12 22:13:34 字数 1667 浏览 2 评论 0原文

我在后端代码中实现了Google Cloud Vision服务。我想单元测试该服务,但我不知道如何嘲笑它。

这是我要嘲笑的当前代码。有没有办法注入ImaNeanNotatorClient,以便我嘲笑它?

public class GoogleCloudVisionService : IGoogleCloudVision
{
    private readonly GoogleCloudVisionSettings googleCloudVisionSettings;

    private ImageAnnotatorClient client;

    public GoogleCloudVisionService(IOptions<GoogleCloudVisionSettings> googleCloudVisionSettings)
    {
        this.googleCloudVisionSettings = googleCloudVisionSettings.Value.WithParsedKey();

        var credential = GoogleCredential.FromJson(this.googleCloudVisionSettings.ApiJson);

        ImageAnnotatorClientBuilder clientBuilder = new ImageAnnotatorClientBuilder();
        clientBuilder.Credential = credential;

        client = clientBuilder.Build();
    }

    public async Task<SafeSearchAnnotation> GetImageAnnotation(byte[] imageBytes)
    {
        var image = Image.FromBytes(imageBytes);

        var annotation = await client.DetectSafeSearchAsync(image);

        return annotation;
    }

    public async Task<bool> IsImageSafe(byte[] imageBytes)
    {
        var annotations = await GetImageAnnotation(imageBytes);

        var isSafe = annotations.Adult < googleCloudVisionSettings.Annotations.Adult &&
            annotations.Racy < googleCloudVisionSettings.Annotations.Racy &&
            annotations.Violence < googleCloudVisionSettings.Annotations.Violence &&
            annotations.Medical < googleCloudVisionSettings.Annotations.Medical &&
            annotations.Spoof < googleCloudVisionSettings.Annotations.Spoof;

        return isSafe;
    }
}

I've implemented a Google Cloud Vision service in my backend code. I want to unit test the service but I don't know how to mock it.

Here's my current code that I'm going to mock. Is there a way to inject the ImageAnnotatorClient so I could mock it?

public class GoogleCloudVisionService : IGoogleCloudVision
{
    private readonly GoogleCloudVisionSettings googleCloudVisionSettings;

    private ImageAnnotatorClient client;

    public GoogleCloudVisionService(IOptions<GoogleCloudVisionSettings> googleCloudVisionSettings)
    {
        this.googleCloudVisionSettings = googleCloudVisionSettings.Value.WithParsedKey();

        var credential = GoogleCredential.FromJson(this.googleCloudVisionSettings.ApiJson);

        ImageAnnotatorClientBuilder clientBuilder = new ImageAnnotatorClientBuilder();
        clientBuilder.Credential = credential;

        client = clientBuilder.Build();
    }

    public async Task<SafeSearchAnnotation> GetImageAnnotation(byte[] imageBytes)
    {
        var image = Image.FromBytes(imageBytes);

        var annotation = await client.DetectSafeSearchAsync(image);

        return annotation;
    }

    public async Task<bool> IsImageSafe(byte[] imageBytes)
    {
        var annotations = await GetImageAnnotation(imageBytes);

        var isSafe = annotations.Adult < googleCloudVisionSettings.Annotations.Adult &&
            annotations.Racy < googleCloudVisionSettings.Annotations.Racy &&
            annotations.Violence < googleCloudVisionSettings.Annotations.Violence &&
            annotations.Medical < googleCloudVisionSettings.Annotations.Medical &&
            annotations.Spoof < googleCloudVisionSettings.Annotations.Spoof;

        return isSafe;
    }
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

迷你仙 2025-02-19 22:13:34

在我们的代码库中查找了一些示例以

public class GoogleCloudVisionServiceUnitTests
{
    private Infrastructure.GoogleCloud.Api api;

    public GoogleCloudVisionServiceUnitTests()
    {
        var faker = new Faker<Infrastructure.GoogleCloud.Api>()
                .RuleFor(x => x.Type, f => f.Random.String2(6))
                .RuleFor(x => x.ProjectId, f => f.Random.String2(6))
                .RuleFor(x => x.PrivateKeyId, f => f.Random.String2(6))
                .RuleFor(x => x.PrivateKey, f => f.Random.String2(6))
                .RuleFor(x => x.ClientEmail, f => f.Random.String2(6))
                .RuleFor(x => x.ClientId, f => f.Random.String2(6))
                .RuleFor(x => x.AuthUri, f => f.Random.String2(6))
                .RuleFor(x => x.TokenUri, f => f.Random.String2(6))
                .RuleFor(x => x.AuthProviderUrl, f => f.Random.String2(6))
                .RuleFor(x => x.ClientCertUrl, f => f.Random.String2(6));

        api = faker.Generate(1).First();
    }

    [Fact]
    public async Task GivenSafeImage_ShouldReturnAnnotations()
    {
        // Arrange
        var faker = new Faker();
        var expectedAnnotation = new SafeSearchAnnotation
        {
            Adult = Likelihood.Likely,
            Racy = Likelihood.Likely,
            Medical = Likelihood.Likely,
            Spoof = Likelihood.Likely,
            Violence = Likelihood.Likely
        };

        var mockOptions = new Mock<ImageAnnotatorClient>();
        mockOptions.Setup(mock => mock.DetectSafeSearchAsync(It.IsAny<Image>(), It.IsAny<ImageContext>(), It.IsAny<CallSettings>()))
            .ReturnsAsync(expectedAnnotation);

        var json = JsonConvert.SerializeObject(api);
        byte[] bytes = Encoding.Default.GetBytes(json);

        var googleCloudVisionSettings = new GoogleCloudVisionSettings
        {
            Key = Convert.ToBase64String(bytes),
            Annotations = new Annotations
            {
                Adult = Likelihood.Likely,
                Racy = Likelihood.Likely,
                Medical = Likelihood.Likely,
                Spoof = Likelihood.Likely,
                Violence = Likelihood.Likely
            }
        };

        // Act
        var googleCloudVisionService = new GoogleCloudVisionService(mockOptions.Object, Options.Create(googleCloudVisionSettings));

        var annotations = await googleCloudVisionService.GetImageAnnotation(faker.Random.Bytes(512));

        // Assert
        annotations.Adult.Should().Be(googleCloudVisionSettings.Annotations.Adult);
        annotations.Racy.Should().Be(googleCloudVisionSettings.Annotations.Racy);
        annotations.Medical.Should().Be(googleCloudVisionSettings.Annotations.Medical);
        annotations.Spoof.Should().Be(googleCloudVisionSettings.Annotations.Spoof);
        annotations.Violence.Should().Be(googleCloudVisionSettings.Annotations.Violence);
    }

    [Fact]
    public async Task GivenSafeImage_ShouldReturnTrue()
    {
        // Arrange
        var faker = new Faker();
        var expectedAnnotation = new SafeSearchAnnotation
        {
            Adult = Likelihood.VeryUnlikely,
            Racy = Likelihood.VeryUnlikely,
            Medical = Likelihood.VeryUnlikely,
            Spoof = Likelihood.VeryUnlikely,
            Violence = Likelihood.VeryUnlikely
        };

        var mockOptions = new Mock<ImageAnnotatorClient>();
        mockOptions.Setup(mock => mock.DetectSafeSearchAsync(It.IsAny<Image>(), It.IsAny<ImageContext>(), It.IsAny<CallSettings>()))
            .ReturnsAsync(expectedAnnotation);

        var json = JsonConvert.SerializeObject(api);
        byte[] bytes = Encoding.Default.GetBytes(json);

        var googleCloudVisionSettings = new GoogleCloudVisionSettings
        {
            Key = Convert.ToBase64String(bytes),
            Annotations = new Annotations
            {
                Adult = Likelihood.Likely,
                Racy = Likelihood.Likely,
                Medical = Likelihood.Likely,
                Spoof = Likelihood.Likely,
                Violence = Likelihood.Likely
            }
        };

        // Act
        var googleCloudVisionService = new GoogleCloudVisionService(mockOptions.Object, Options.Create(googleCloudVisionSettings));

        var isSafe = await googleCloudVisionService.IsImageSafe(faker.Random.Bytes(512));

        // Assert
        Assert.True(isSafe);
    }

    [Fact]
    public async Task GivenUnsafeImage_ShouldReturnFalse()
    {
        // Arrange
        var faker = new Faker();
        var expectedAnnotation = new SafeSearchAnnotation
        {
            Adult = Likelihood.VeryLikely,
            Racy = Likelihood.VeryLikely,
            Medical = Likelihood.VeryLikely,
            Spoof = Likelihood.VeryLikely,
            Violence = Likelihood.VeryLikely
        };

        var mockOptions = new Mock<ImageAnnotatorClient>();
        mockOptions.Setup(mock => mock.DetectSafeSearchAsync(It.IsAny<Image>(), It.IsAny<ImageContext>(), It.IsAny<CallSettings>()))
            .ReturnsAsync(expectedAnnotation);

        var json = JsonConvert.SerializeObject(api);
        byte[] bytes = Encoding.Default.GetBytes(json);

        var googleCloudVisionSettings = new GoogleCloudVisionSettings
        {
            Key = Convert.ToBase64String(bytes),
            Annotations = new Annotations
            {
                Adult = Likelihood.Likely,
                Racy = Likelihood.Likely,
                Medical = Likelihood.Likely,
                Spoof = Likelihood.Likely,
                Violence = Likelihood.Likely
            }
        };

        // Act
        var googleCloudVisionService = new GoogleCloudVisionService(mockOptions.Object, Options.Create(googleCloudVisionSettings));

        var isSafe = await googleCloudVisionService.IsImageSafe(faker.Random.Bytes(512));

        // Assert
        Assert.False(isSafe);
    }
}

使其模拟之后,我终于获得了一个工作代码,我需要添加一个新的构造函数,以便我可以通过mock&lt; ImageAnnotatorClient&gt;的实例。

public GoogleCloudVisionService(ImageAnnotatorClient client, IOptions<GoogleCloudVisionSettings> googleCloudVisionSettings)
{
    this.client = client;
    this.googleCloudVisionSettings = googleCloudVisionSettings.Value.WithParsedKey();
}

Finally got a working code after looking some examples in our codebase

public class GoogleCloudVisionServiceUnitTests
{
    private Infrastructure.GoogleCloud.Api api;

    public GoogleCloudVisionServiceUnitTests()
    {
        var faker = new Faker<Infrastructure.GoogleCloud.Api>()
                .RuleFor(x => x.Type, f => f.Random.String2(6))
                .RuleFor(x => x.ProjectId, f => f.Random.String2(6))
                .RuleFor(x => x.PrivateKeyId, f => f.Random.String2(6))
                .RuleFor(x => x.PrivateKey, f => f.Random.String2(6))
                .RuleFor(x => x.ClientEmail, f => f.Random.String2(6))
                .RuleFor(x => x.ClientId, f => f.Random.String2(6))
                .RuleFor(x => x.AuthUri, f => f.Random.String2(6))
                .RuleFor(x => x.TokenUri, f => f.Random.String2(6))
                .RuleFor(x => x.AuthProviderUrl, f => f.Random.String2(6))
                .RuleFor(x => x.ClientCertUrl, f => f.Random.String2(6));

        api = faker.Generate(1).First();
    }

    [Fact]
    public async Task GivenSafeImage_ShouldReturnAnnotations()
    {
        // Arrange
        var faker = new Faker();
        var expectedAnnotation = new SafeSearchAnnotation
        {
            Adult = Likelihood.Likely,
            Racy = Likelihood.Likely,
            Medical = Likelihood.Likely,
            Spoof = Likelihood.Likely,
            Violence = Likelihood.Likely
        };

        var mockOptions = new Mock<ImageAnnotatorClient>();
        mockOptions.Setup(mock => mock.DetectSafeSearchAsync(It.IsAny<Image>(), It.IsAny<ImageContext>(), It.IsAny<CallSettings>()))
            .ReturnsAsync(expectedAnnotation);

        var json = JsonConvert.SerializeObject(api);
        byte[] bytes = Encoding.Default.GetBytes(json);

        var googleCloudVisionSettings = new GoogleCloudVisionSettings
        {
            Key = Convert.ToBase64String(bytes),
            Annotations = new Annotations
            {
                Adult = Likelihood.Likely,
                Racy = Likelihood.Likely,
                Medical = Likelihood.Likely,
                Spoof = Likelihood.Likely,
                Violence = Likelihood.Likely
            }
        };

        // Act
        var googleCloudVisionService = new GoogleCloudVisionService(mockOptions.Object, Options.Create(googleCloudVisionSettings));

        var annotations = await googleCloudVisionService.GetImageAnnotation(faker.Random.Bytes(512));

        // Assert
        annotations.Adult.Should().Be(googleCloudVisionSettings.Annotations.Adult);
        annotations.Racy.Should().Be(googleCloudVisionSettings.Annotations.Racy);
        annotations.Medical.Should().Be(googleCloudVisionSettings.Annotations.Medical);
        annotations.Spoof.Should().Be(googleCloudVisionSettings.Annotations.Spoof);
        annotations.Violence.Should().Be(googleCloudVisionSettings.Annotations.Violence);
    }

    [Fact]
    public async Task GivenSafeImage_ShouldReturnTrue()
    {
        // Arrange
        var faker = new Faker();
        var expectedAnnotation = new SafeSearchAnnotation
        {
            Adult = Likelihood.VeryUnlikely,
            Racy = Likelihood.VeryUnlikely,
            Medical = Likelihood.VeryUnlikely,
            Spoof = Likelihood.VeryUnlikely,
            Violence = Likelihood.VeryUnlikely
        };

        var mockOptions = new Mock<ImageAnnotatorClient>();
        mockOptions.Setup(mock => mock.DetectSafeSearchAsync(It.IsAny<Image>(), It.IsAny<ImageContext>(), It.IsAny<CallSettings>()))
            .ReturnsAsync(expectedAnnotation);

        var json = JsonConvert.SerializeObject(api);
        byte[] bytes = Encoding.Default.GetBytes(json);

        var googleCloudVisionSettings = new GoogleCloudVisionSettings
        {
            Key = Convert.ToBase64String(bytes),
            Annotations = new Annotations
            {
                Adult = Likelihood.Likely,
                Racy = Likelihood.Likely,
                Medical = Likelihood.Likely,
                Spoof = Likelihood.Likely,
                Violence = Likelihood.Likely
            }
        };

        // Act
        var googleCloudVisionService = new GoogleCloudVisionService(mockOptions.Object, Options.Create(googleCloudVisionSettings));

        var isSafe = await googleCloudVisionService.IsImageSafe(faker.Random.Bytes(512));

        // Assert
        Assert.True(isSafe);
    }

    [Fact]
    public async Task GivenUnsafeImage_ShouldReturnFalse()
    {
        // Arrange
        var faker = new Faker();
        var expectedAnnotation = new SafeSearchAnnotation
        {
            Adult = Likelihood.VeryLikely,
            Racy = Likelihood.VeryLikely,
            Medical = Likelihood.VeryLikely,
            Spoof = Likelihood.VeryLikely,
            Violence = Likelihood.VeryLikely
        };

        var mockOptions = new Mock<ImageAnnotatorClient>();
        mockOptions.Setup(mock => mock.DetectSafeSearchAsync(It.IsAny<Image>(), It.IsAny<ImageContext>(), It.IsAny<CallSettings>()))
            .ReturnsAsync(expectedAnnotation);

        var json = JsonConvert.SerializeObject(api);
        byte[] bytes = Encoding.Default.GetBytes(json);

        var googleCloudVisionSettings = new GoogleCloudVisionSettings
        {
            Key = Convert.ToBase64String(bytes),
            Annotations = new Annotations
            {
                Adult = Likelihood.Likely,
                Racy = Likelihood.Likely,
                Medical = Likelihood.Likely,
                Spoof = Likelihood.Likely,
                Violence = Likelihood.Likely
            }
        };

        // Act
        var googleCloudVisionService = new GoogleCloudVisionService(mockOptions.Object, Options.Create(googleCloudVisionSettings));

        var isSafe = await googleCloudVisionService.IsImageSafe(faker.Random.Bytes(512));

        // Assert
        Assert.False(isSafe);
    }
}

To make it mock-able, I need to add a new constructor so I can pass an instance of Mock<ImageAnnotatorClient>

public GoogleCloudVisionService(ImageAnnotatorClient client, IOptions<GoogleCloudVisionSettings> googleCloudVisionSettings)
{
    this.client = client;
    this.googleCloudVisionSettings = googleCloudVisionSettings.Value.WithParsedKey();
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文