Mocking a method to throw an exception (moq), but otherwise act like the mocked object?

前端 未结 3 766
天涯浪人
天涯浪人 2020-12-15 02:38

I have a Transfer class, simplified it looks like this:

public class Transfer
{
    public virtual IFileConnection source { get; set; }
    publ         


        
3条回答
  •  自闭症患者
    2020-12-15 03:00

    Here's how you can mock your FileConnection

    Mock fileConnection = new Mock(
                                                               MockBehavior.Strict);
    fileConnection.Setup(item => item.Get(It.IsAny,It.IsAny))
                  .Throws(new IOException());
    

    Then instantiate your Transfer class and use the mock in your method call

    Transfer transfer = new Transfer();
    transfer.GetFile(fileConnection.Object, someRemoteFilename, someLocalFileName);
    

    Update:

    First of all you have to mock your dependencies only, not the class you are testing(Transfer class in this case). Stating those dependencies in your constructor make it easy to see what services your class needs to work. It also makes it possible to replace them with fakes when you are writing your unit tests. At the moment it's impossible to replace those properties with fakes.

    Since you are setting those properties using another dependency, I would write it like this:

    public class Transfer
    {
        public Transfer(IInternalConfig internalConfig)
        {
            source = internalConfig.GetFileConnection("source");
            destination = internalConfig.GetFileConnection("destination");
        }
    
        //you should consider making these private or protected fields
        public virtual IFileConnection source { get; set; }
        public virtual IFileConnection destination { get; set; }
    
        public virtual void GetFile(IFileConnection connection, 
            string remoteFilename, string localFilename)
        {
            connection.Get(remoteFilename, localFilename);
        }
    
        public virtual void PutFile(IFileConnection connection, 
            string localFilename, string remoteFilename)
        {
            connection.Get(remoteFilename, localFilename);
        }
    
        public virtual void TransferFiles(string sourceName, string destName)
        {
            var tempName = Path.GetTempFileName();
            GetFile(source, sourceName, tempName);
            PutFile(destination, tempName, destName);
        }
    }
    

    This way you can mock internalConfig and make it return IFileConnection mocks that does what you want.

提交回复
热议问题