There are several problems with your approach. For starters, you can only fake virtual methods (or abstract ones, or methods defined on interfaces). I assume that WebService.WebServiceClient.getCustomerName
is not virtual, so here's an alternative to @Micael's answer that will get you around that. I've used it many times in the past:
Like Micael says, create an interface instead which holds the functionality the webservice provides.
public interface ICustomerData
{
CustomerName GetCustomerName(CustomerNumber number);
}
Then you can make your production collaborator CustomerData
as he did, or if WebService.WebServiceClient
is not sealed, you can do this:
public class CustomerData: WebService.WebServiceClient, ICustomerData
{}
You will need to find a way to supply an implementation of ICustomerData
to your production code so that you can use the actual implementation during production and a fake during the tests, which I talk about right now:
The second problem is that in your test, you're attempting to fake calls to WebServiceClient.CustomerNumber
, which feels like a type to me, not an actual object that you're dealing with. Following along from our step above, you want to fake the ICustomerData
interface:
var fakeCustomerData = A.Fake<ICustomerData>();
var someCustomerName = getACustomerNameSomehow();
A.CallTo(() => fakeCustomerData.GetCustomerName(A<CustomerNumber>.Ignored)
.Returns(someCustomerName);
This will make sure your fake returns someCustomerName
whenever GetCustomerName
is called. I changed someCustomerName
from a fake because you may not need it to be a fake - if it's easy to create a CustomerName
object to return from your fake service, I'd just do that. Only if you need to change its behaviour, or it's almost impossible to create, would I use a fake.
After the fake is configured, you should call some method on your production class (which you said was called CustomerName
, just like the type returned from GetCustomerName
?), that will eventually call the ICustomerData
collaborator. In your original code, you're calling a method on the fake directly, which only tests the fake, not your own code. So instead you might have something like
var customerNameService = new CustomerName(fakeCustomerData);
var foundCustomerName = customerNameService.GetACustomerNameFromANumber(someCustomerNumber);
// in my imagination, GetACustomerNameFromANumber calls ICustomerData.GetCustomerName
// now do something to check if the foundCustomerName is right, or whatever