2017-06-07 5 views
0

Je veux faux appel service GetCustomerName ici et se moquer avec des données faussesComment se moquer d'une classe de service SOAP en C#

Ma classe est « CustomerName » qui appelle un appel SOAPService qui retourne le CustomerName pour un CustomerNumber. Je veux simuler l'appel de SOAPService pour retourner un fakedata.

classe CustomerName:

using (WebService.WebServiceClient CustomerData = new WebService.WebServiceClient()) 
{ 
     WebServiceClient.TestResponse resp = CustomerData.getCustomerName(customerNumber); 
     resp.CustomerName; 
} 

J'ai essayé de faire ces

var FakeWebService = A.Fake<WebServiceClient>(); 
var FakeCustomerName=A.Fake<CustomerName>(); 

Je truqué les appels ici et la réponse Faux est une valeur

A.CallTo(WebServiceClient.CustomerNumber).WithNonVoidReturnType().Returns(FakeResponse); 
fakeCustomerName = FakeCustomerData.GetCustomerName(CustomerNumber); 

Le problème que je le visage est c'est obtenir les données du point de terminaison réel au lieu de fakedata?

Je ne suis pas clair sur la façon de le faire ..

Répondre

1

Au lieu de webservice se référant à directement et donc essayer de se moquer de lui-même le webservice, créez une interface à la place qui détient la fonctionnalité webservice offre.

public interface ICustomerData 
{ 
    CustomerName GetCustomerName(CustomerNumber number); 
} 

Ensuite, effectuez deux implémentations. Un qui appelle la webservice réelle, et qui vous pouvez utiliser pour les tests:

public class CustomerData : ICustomerData 
{ 
    CustomerName GetCustomerName(CustomerNumber number) 
    { 
     return CustomerData.GetCustomerName(number); 
    } 

    public CustomerData() 
    { 
     CustomerData = new WebService.WebServiceClient(); 
    } 
    private WebService.WebServiceClient CustomerData; 
} 


public class DelegatedCustomerData : ICustomerData 
{ 
    public Func<CustomerNumber,CustomerName> GetCustomerName {get;set;} 


    CustomerName ICustomerData.GetCustomerName(CustomerNumber number) => GetCustomerName(number); 

} 

Cette dernière classe déléguée est juste un exemple sur la façon de se moquer de la classe, mais je préfère personnellement.

+0

Que la même chose peut être fait en utilisant FakeItEasy? – Shan

0

Votre approche présente plusieurs problèmes. Pour commencer, vous ne pouvez que truquer des méthodes virtuelles (ou abstraites, ou des méthodes définies sur des interfaces). Je suppose que WebService.WebServiceClient.getCustomerName n'est pas virtuel, alors voici une alternative à la réponse de @ Micael qui vous permettra de contourner cela. Je l'ai utilisé plusieurs fois dans le passé:

Comme le dit Micael, créez plutôt une interface qui contient les fonctionnalités fournies par le service Web.

public interface ICustomerData 
{ 
    CustomerName GetCustomerName(CustomerNumber number); 
} 

Ensuite, vous pouvez faire votre collaborateur de production CustomerData comme il l'a fait, ou si WebService.WebServiceClient n'est pas scellé, vous pouvez le faire:

public class CustomerData: WebService.WebServiceClient, ICustomerData 
{} 

Vous aurez besoin de trouver un moyen de fournir une implémentation de ICustomerData à votre code de production de sorte que vous pouvez utiliser l'implémentation réelle pendant la production et un faux pendant les tests dont je parle maintenant:

Le deuxième problème est que dans votre test, vous essayez de faux appels à WebServiceClient.CustomerNumber, qui me semble être un type, pas un objet réel avec lequel vous avez affaire. A la suite le long de notre étape ci-dessus, vous voulez faux l'interface ICustomerData:

var fakeCustomerData = A.Fake<ICustomerData>(); 
var someCustomerName = getACustomerNameSomehow(); 

A.CallTo(() => fakeCustomerData.GetCustomerName(A<CustomerNumber>.Ignored) 
     .Returns(someCustomerName); 

Cela fera en sorte vos déclarations fausses someCustomerName chaque fois que GetCustomerName est appelé. J'ai changé someCustomerName d'un faux parce que vous ne pouvez pas avoir besoin d'être un faux - s'il est facile de créer un objet CustomerName pour revenir de votre faux service, je ferais juste cela.Seulement si vous avez besoin de changer son comportement, ou il est presque impossible de créer, j'utiliserais un faux.

Après le faux est configuré, vous devez appeler une méthode sur votre classe de production (qui vous dit a été appelé CustomerName, tout comme le type de retour GetCustomerName?), Qui finira par appeler le collaborateur ICustomerData. Dans votre code d'origine, vous appelez directement une méthode sur le faux, qui ne teste que le faux, pas votre propre code. Donc à la place, vous pourriez avoir quelque chose comme

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 
+0

Le FakeCustomerData appelle un WebService..Je suis un peu confus ici..Je veux me moquer du WebService qui est déclaré dans l'interface "ICustomerData" Comme l'exemple que j'ai écrit ici est presque différent de celui d'origine. .Je suis tellement confus (Autant que je peux voir je n'ai pas une interface où je peux le forcer à retourner la production et à fausser les données séparément – Shan

+0

Je ne comprends pas entièrement votre commentaire, mais permettez-moi d'essayer de faire la lumière .. la façon de faire ce que vous voulez/ce que vous voulez est de déclarer une classe concrète (que vous allez tester) qui accepte le collaborateur injecté (souvent via un constructeur ou une injection de propriété) sous la forme d'une interface. l'implémentation concrète du collaborateur (le service web), et dans le test, vous injectez l'interface truquée J'espère que cela aide. par les extraits d'échantillon et vos noms de variable et de classe, ou j'essaierais de fournir un exemple complet. –

+0

Ça ne marchera pas parce que le service que j'appelle n'est pas virtuel c'est un moyen privé que j'ai essayé avec un simulacre, faux et rien ne fonctionne! – Shan