Greg Burghardt
Greg Burghardt

Reputation: 18783

How to mock SoapException using Moq to unit test error handling

I've inherited a small console application that makes calls to a SOAP web service. It's a tragic mess of nested try-catches that log exceptions in various ways, and I'd like to wrap some test coverage around how it behaves when a SoapException gets thrown.

Question: How can I mock a class like SoapException using Moq when I can't mock an interface and I can't make properties or methods "virtual"?

A little more explanation:

To test this error handling, I need to control the Actor property of the SoapException object, as well as the Detail property in order to verify the error handling.

A snippet of my unit test code:

[TestMethod]
public void MyTestMethod()
{
    Mock<SoapException> soapMock = new Mock<SoapException>(MockBehavior.Strict);

    soapMock.SetupGet<string>(ex => ex.Actor).Returns("Test Actor");

Since I'm mocking a concrete class, and the Actor property is not marked "Virtual", Moq is throwing this exception when executing the SetupGet(...) line during the test run:

System.NotSupportedException: Invalid setup on a non-virtual (overridable in VB) member: ex => ex.Actor

After some reading, the ideal answer is to mock an interface, which I am unable to do in this case. Since this is a class baked in to the .NET framework, I also can't magically mark the Actor property as virtual.

How can I mock a SoapException, or is there a different way I can verify the error handling?

As an aside, I first dove into creating an actual SoapException with some XML nodes inside it, but I quickly fell down the rabbit hole of programmatically creating an XML document tree. I can do it, but it would require many more lines of test setup code, which I'd like to avoid if possible.

Upvotes: 4

Views: 1263

Answers (2)

vpsivam
vpsivam

Reputation: 11

I was in a same situation to mock SoapException. I used the constructor of SoapException to pass Detail, Actor etc. Below is using Rhino Mocks.

//Build your xmlDocument 
    SoapException mockSoapException = MockRepository.GenerateMock<SoapException>("Mock SoapException", new XmlQualifiedName(), "TEST", xmlDocument); 

Upvotes: 1

Adarsh Shah
Adarsh Shah

Reputation: 6775

Its not possible to mock it using Moq. One option is to use Shim from Microsoft Fakes Framework. You can use it in scenarios where the code you are trying to mock doesn't use interface or is a virtual method(like in your scenario).

See below explanation of Shim from msdn.

A shim modifies the compiled code of your application at run time so that instead of making a specified method call, it runs the shim code that your test provides. Shims can be used to replace calls to assemblies that you cannot modify, such .NET assemblies.

http://msdn.microsoft.com/en-us/library/hh549175.aspx

Note that Fakes framework is only available with Visual Studio Ultimate or Premium.

Upvotes: 1

Related Questions