Reputation: 25221
I'm testing a service that interfaces with a third-party system. The method exposed by the API returns objects that look something like this:
public class Thing
{
public string Name { get {...} }
public string Description { get {...} }
public Thing(string someUri)
{
/* Do some secret internal stuff and
populate all my properties. */
}
}
I need to mock these properties in order to test that my service behaves correctly according to the objects returned.
The objects are instances of a concrete class that does not implement any interfaces that I can mock. The backing fields of these properties are set in the constructor of Thing
, which takes a URI, goes off and fetches the object in some tightly-coupled third-party system and presumably sets the backing fields directly.
All of this means that I have no way to mock the properties - I can't set them directly, I can't mock an interface and I can't mock out the constructor dependencies and set the properties that way (which would diminish the usefulness of my tests anyway).
Is there any way around this?
Upvotes: 1
Views: 1379
Reputation: 2175
You could just wrap the Thing -- this probably isn't the answer you're looking for because it will involve changes to the application code to support your unit testing, but it will result in a more loosely coupled code base and might make your life easier in the long run.
Create a ThingWrapper
class that takes a Thing
as a constructor argument and whose properties call the getters on the wrapped Thing
instance. You can then
virtual
and mock the wrapper directly (less code)Hope this helps, sorry if I'm just stating the obvious :/
Upvotes: 1
Reputation: 5636
Assuming you are using VS2012.2 or VS2013 in either Premium or Ultimate Edition, shims should get you what you need. They allow for "shimming" properties and constructors, ideally only for scenarios like the one you find yourself in (third-party library that doesn't use interfaces).
After adding a Fakes assembly for your library in your unit test project, you'd do something like this in your unit test:
using (ShimsContext.Create())
{
ShimThing.ConstructorString = (@this, value) => {
var shim = new ShimThing(@this) {
NameGet = () => "Your Desired Name",
DescriptionGet = () => "Your Desired Description"
};
};
//do whatever you need to do that creates a Thing object
}
I wrote this example without actually trying it out, so the syntax of the ShimThing constructor might be slightly off.
Upvotes: 1
Reputation: 571
You can use Shims (build into visual studio) to fake a Thing
http://msdn.microsoft.com/en-us/library/hh549175.aspx
Upvotes: 1