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

c#, mocking, moq, unit-testing

Solution

This is how I managed to do what I was trying to do:

[Test]
public void TransferHandlesDisconnect()
{
    // ... set up config here
    var methodTester = new Mock<Transfer>(configInfo);
    methodTester.CallBase = true;
    methodTester
        .Setup(m => 
            m.GetFile(
                It.IsAny<IFileConnection>(), 
                It.IsAny<string>(), 
                It.IsAny<string>()
            ))
        .Throws<System.IO.IOException>();

    methodTester.Object.TransferFiles("foo1", "foo2");
    Assert.IsTrue(methodTester.Object.Status == TransferStatus.TransferInterrupted);
}

If there is a problem with this method, I would like to know; the other answers suggest I am doing this wrong, but this was exactly what I was trying to do.

Problem

I have a `Transfer` class, simplified it looks like this: ``` public class Transfer { 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) { source = internalConfig.GetFileConnection("source"); destination = internalConfig.GetFileConnection("destination"); var tempName = Path.GetTempFileName(); GetFile(source, sourceName, tempName); PutFile(destination, tempName, destName); } } ``` The simplified version of the `IFileConnection` interface looks like this: ``` public interface IFileConnection { void Get(string remoteFileName, string localFileName); void Put(string localFileName, string remoteFileName); } ``` The real class is supposed to handle a `System.IO.IOException` that is thrown when the `IFileConnection` concrete classes loses connectivity with the remote, sending out emails and what not. I would like to use Moq to create a `Transfer` class, and use it as my concrete `Transfer` class in all properties and methods, except when the `GetFile` method is invoked - then I want it to throw a `System.IO.IOException` and make sure the `Transfer` class handles it properly. Am I using the right tool for the job? Am I going about this the right way? And how would I write the setup for that unit test for `NUnit`?

Original source