2017-03-07 1 views
2

je voudrais mockup la classe RESTClient à des fins de testComment se moquer de la bibliothèque portable RestSharp dans l'unité de test

public class DataServices : IDataServices 
{ 
    private readonly IRestClient _restClient; 


    public DataServices(IRestClient restClient) 
    { 
     _restClient = restClient; 
    } 

    public async Task<User> GetUserByUserName(string userName) 
    { 
     User user = null; 

     // create a new request 
     var restRequest = new RestRequest("User", Method.GET); 
     // create REST parameters 
     restRequest.AddParameter("userName", userName, ParameterType.QueryString); 
     // execute the REST request 
     var restResponse = await _restClient.Execute<User>(restRequest); 
     if (restResponse.StatusCode.Equals(HttpStatusCode.OK)) 
     { 
      user = restResponse.Data; 
     } 
     return user; 
    } 

} 

Ma classe de test:

[TestClass] 
public class DataServicesTest 
{ 
    public static IRestClient MockRestClient<T>(HttpStatusCode httpStatusCode, string json) 
    { 
     var mockIRestClient = new Mock<IRestClient>(); 
     mockIRestClient.Setup(x => x.Execute<T>(It.IsAny<IRestRequest>())) 
      .Returns(new RestResponse<T> 
      { 
       Data = JsonConvert.DeserializeObject<T>(json), 
       StatusCode = httpStatusCode 
      }); 
     return mockIRestClient.Object; 
    } 

    [TestMethod] 
    public async void GetUserByUserName() 
    { 
     var dataServices = new DataServices(MockRestClient<User>(HttpStatusCode.OK, "my json code")); 
     var user = await dataServices.GetUserByUserName("User1"); 
     Assert.AreEqual("User1", user.Username); 
    } 
} 

Mais je ne peux pas instancier l'objet RestResponse , j'ai l'erreur suivante:

.Returns(new RestResponse<T> 
{ 
    Data = JsonConvert.DeserializeObject<T>(json), 
    StatusCode = httpStatusCode 
}); 

Cannot access protected internal constructor 'RestResponse' here.

Comment puis-je contourner ce problème? J'utilise le paquet nuget FubarCoder.RestSharp sur une bibliothèque portable Xamarin.

+0

Mock '' IRestResponse et retour que je – Nkosi

Répondre

3

Mock IRestResponse<T> et retour qui

public static IRestClient MockRestClient<T>(HttpStatusCode httpStatusCode, string json) 
    where T : new() { 
    var data = JsonConvert.DeserializeObject<T>(json) 
    var response = new Mock<IRestResponse<T>>(); 
    response.Setup(_ => _.StatusCode).Returns(httpStatusCode); 
    response.Setup(_ => _.Data).Returns(data); 

    var mockIRestClient = new Mock<IRestClient>(); 
    mockIRestClient 
     .Setup(x => x.Execute<T>(It.IsAny<IRestRequest>())) 
     .ReturnsAsync(response.Object); 
    return mockIRestClient.Object; 
} 

Le test devrait également être mis à jour pour être async ainsi

[TestMethod] 
public async Task GetUserByUserName() { 
    //Arrange 
    var client = MockRestClient<User>(HttpStatusCode.OK, "my json code"); 
    var dataServices = new DataServices(client); 
    //Act 
    var user = await dataServices.GetUserByUserName("User1"); 
    //Assert 
    Assert.AreEqual("User1", user.Username); 
} 
+0

@Nkosi a essayé d'utiliser votre méthode et je reçois l'erreur suivante: 'T' doit être un type non-abstrait avec un constructeur public sans paramètre afin de l'utiliser comme paramètre 'T' dans le type générique ou la méthode 'RestClient.Execute (RestRequest)'. As-tu une idée de pourquoi je reçois ça? – alminh

+0

@alminh Comme l'explique le message d'erreur, il est probable que vous utilisiez un type abstrait. – Nkosi

+1

Merci pour la réponse. J'avais besoin d'ajouter une contrainte où T: new() sur la méthode MockRestClient. Cela fonctionne bien maintenant. – alminh