GoogleCloudVision c# - how to unit test the service

120

Question: GoogleCloudVision c# - how to unit test the service

I've implemented a Google Cloud Vision service in my backend code. I want c# error 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. c# error 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;     } } 

Total Answers: 1

86

Answers 1: of GoogleCloudVision c# - how to unit test the service

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(); }