Can not instantiate proxy of class. Could not find a parameterless constructor
Asked Answered
C

2

14

I am facing highlighted issue while writing test cases with xUnit and Moq in .Net Core

I have written below test case using MSTest Fakes .It is working fine as expected.

 [TestClass]
public class TestBlobServiceProvider
{
    private Common.Interfaces.IBlobServiceProvider _iblobprovider;

    public TestBlobServiceProvider()
    {
        Common.Interfaces.IBlobServiceProvider iblobprovider = new BlobServiceProvider();
        this._iblobprovider = iblobprovider;
    }

    public TestBlobServiceProvider(string storageConnectionString)
    { 

    }


    [TestMethod]
    public void Move_Success()
    {
        using (ShimsContext.Create())
        {
            string sourceContainer = "a";
            string destinationContainer = "s";
            string sourceFileName = "d";
            string destinationFileName = "e";

            Microsoft.WindowsAzure.Storage.Blob.Fakes.ShimCloudBlockBlob sourceFile = new Microsoft.WindowsAzure.Storage.Blob.Fakes.ShimCloudBlockBlob ();
            Microsoft.WindowsAzure.Storage.Blob.Fakes.ShimCloudBlockBlob destFile = new Microsoft.WindowsAzure.Storage.Blob.Fakes.ShimCloudBlockBlob();

            Microsoft.WindowsAzure.Storage.Blob.Fakes.ShimCloudBlockBlob.AllInstances.StartCopyCloudBlockBlobAccessConditionAccessConditionBlobRequestOptionsOperationContext = (x, y, z, d, e,s) =>
            { 
                     return "Hi"; 
            };

            Microsoft.WindowsAzure.Storage.Blob.Fakes.ShimCloudBlob.AllInstances.DeleteDeleteSnapshotsOptionAccessConditionBlobRequestOptionsOperationContext = (x, y, z, d, e) =>
           {

           };

            Microsoft.WindowsAzure.Storage.Blob.Fakes.ShimCloudBlobClient.AllInstances.GetContainerReferenceString = (x, y) =>
            {
                return new Microsoft.WindowsAzure.Storage.Blob.Fakes.ShimCloudBlobContainer();
            };

            Microsoft.WindowsAzure.Storage.Blob.Fakes.ShimCloudBlobContainer.AllInstances.CreateIfNotExistsAsync = (x) =>
            {
                return Task.Run(() =>
                {
                   return new bool();
                });
            };

            Microsoft.WindowsAzure.Storage.Blob.Fakes.ShimCloudBlobContainer.AllInstances.GetBlockBlobReferenceString = (x, y) =>
            {
                return new Microsoft.WindowsAzure.Storage.Blob.Fakes.ShimCloudBlockBlob();

            };


            CDM.Common.Fakes.ShimBlobServiceProvider.AllInstances.GetBlockBlobContainerString = (x, y) =>
            {
                return new Microsoft.WindowsAzure.Storage.Blob.Fakes.ShimCloudBlobContainer();
            };

            this._iblobprovider.Move( sourceContainer,  destinationContainer,  sourceFileName,  destinationFileName);

        }

    }
}

But now we got requirement to migrate to .Net Core . Hence, I started test cases with xUnit as .Net core misses Fakes support.

Below code is with xUnit and Moq

public class TestBlobServiceProvider
{
    private readonly Common.Interfaces.IBlobServiceProvider _iblobprovider;

    public TestBlobServiceProvider()
    {
        Common.Interfaces.IBlobServiceProvider iblobprovider = new BlobServiceProvider();
        this._iblobprovider = iblobprovider;
    }

    [Fact]
    public void Move_Success()
    {
            string sourceContainer = "a";
            string destinationContainer = "s";
            string sourceFileName = "d";
            string destinationFileName = "e";

            var uri = new Uri("https://app.blob.core.windows.net/container/https://app.blob.core.windows.net/container/Accounts/Images/acc.jpg");

            CloudBlockBlob source = null;
            AccessCondition sourceAccessCondition = null;
            AccessCondition destAccessCondition = null;
            BlobRequestOptions options = null;
            OperationContext operationContext = null;
            CloudBlobContainer container = new CloudBlobContainer (uri);
            Task task = null;
            DeleteSnapshotsOption deleteSnapshotsOption = new DeleteSnapshotsOption();


            var mockCloudBlobClient = new Mock<Microsoft.WindowsAzure.Storage.Blob.CloudBlobClient>();
            mockCloudBlobClient.Setup(repo => repo.GetContainerReference("sample")).Returns(container);

            var mockCloudBlobContainer = new Mock<Microsoft.WindowsAzure.Storage.Blob.CloudBlobContainer>();
            mockCloudBlobContainer.Setup(repo => repo.GetBlockBlobReference("sample")).Returns(new CloudBlockBlob(uri));

            mockCloudBlobContainer.Setup(repo => repo.CreateIfNotExistsAsync()).Returns(Task.Run(() =>
            {
                return new bool();
            }));


           var mockCloudBlob = new Mock<Microsoft.WindowsAzure.Storage.Blob.CloudBlob>();
            mockCloudBlob.Setup(repo => repo.DeleteAsync(deleteSnapshotsOption, sourceAccessCondition, options, operationContext)).Returns(task);

            var mockCloudBlockBlob = new Mock<Microsoft.WindowsAzure.Storage.Blob.CloudBlockBlob>();
            mockCloudBlockBlob.Setup(repo => repo.StartCopyAsync(source, sourceAccessCondition, destAccessCondition, options, operationContext)).ReturnsAsync("Hi");

            Common.Interfaces.IBlobServiceProvider obj = new BlobServiceProvider(mockCloudBlobClient.Object, mockCloudBlobContainer.Object, mockCloudBlob.Object, mockCloudBlockBlob.Object);

            obj.Move(sourceContainer, destinationContainer, sourceFileName, destinationFileName);

        //   this._iblobprovider.Move(sourceContainer, destinationContainer, sourceFileName, destinationFileName);

    }
}

I am getting error at

Common.Interfaces.IBlobServiceProvider obj = new BlobServiceProvider(mockCloudBlobClient.Object, mockCloudBlobContainer.Object, mockCloudBlob.Object, mockCloudBlockBlob.Object);`

Error:

Can not instantiate proxy of class: Microsoft.WindowsAzure.Storage.Blob.CloudBlobClient. Could not find a parameterless constructor.

How to resolve above issue

Cumings answered 11/7, 2019 at 12:51 Comment(5)
CloudBlobClient has no paramrterless constructor that moq can use to create a proxy. Hence the error.Corner
What can I do now? Can't I write mock/UnitTest for CloudBlobClient methods. If I don't create Mock for CloudBlobClient methods, then they will throw errors in BlobServiceProvider class methods blocking me to proceed further.Cumings
var mockCloudBlobClient = new Mock<Microsoft.WindowsAzure.Storage.Blob.CloudBlobClient>(new Uri("http://mytest")); try this...Neotype
@Johnny, Thanks .Issue has been resolved.Cumings
@chandrasekhar if the provided answer resolves the issue, mark it as the answer.Corner
N
17

The problem is that moq cannot create CloudBlobClient as it has no parameterless constructor. However moq is capable of creating the object without parameterless constructor but you need to provide arguments.

The simplest approach is to use this constructor

public CloudBlobClient (
    Uri baseUri, System.Net.Http.DelegatingHandler delegatingHandler = null);

and provide the Uri.

Something like:

var mockCloudBlobClient = new Mock<CloudBlobClient>(new Uri("http://mytest"));
Neotype answered 11/7, 2019 at 13:44 Comment(0)
M
4

This comes up often when you are mocking an implementation instead of the interface. If an object has an interface, generally mocking that interface will be much easier.

For instance, imagine this worker class:

//worker.cs
public class TemplateWorker : ITemplateWorker
    {
        private readonly ITemplateRetriever templateRetriever;
        
        public TemplateWorker(ITemplateRetriever templateRetriever)
        {
            this.templateRetriever = templateRetriever ?? 
               throw new ArgumentNullException(nameof(templateRetriever));
        }
     //..class body
     }

If you try to mock this, you'll get the error in this post

tests.cs
var mockWorker = Mock.Of<TemplateWorker>();
//!!Can not instantiate proxy of class TestProject.TemplateWorker : 
//!!  Could not find a parameterless constructor.'

However if I mock the Interface instead...no error! This is great because most of the time in mocking we only care about how this class consumes items in the public contract of its dependencies.

var mockWorker = Mock.Of<ITemplateWorker>();

//setup what should happen when I call its method...
Mock.Get(mockWorker).Setup(x=>x.SomeMethod(....//;
Mazdaism answered 21/7, 2021 at 14:22 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.