Services de tests unitaires avec sérialisation/désérialisation personnalisée

StackOverflow https://stackoverflow.com//questions/9671493

  •  12-12-2019
  •  | 
  •  

Question

J'ai un problème pour tester le service Web qui dispose de son propre mécanisme de dé/sérialisation.

Mon échantillon Task classe utilisée par TaskService:

public class Task
{
    public string TaskName { get; set; }
    public string AuxData { get; set; }

    public static void RegisterCustomSerialization(IAppHost appHost)
    {
        appHost.ContentTypeFilters.Register("application/xml", SerializeTaskToStream, DeserializeTaskFromStream);
    }

    public static void SerializeTaskToStream(IRequestContext requestContext, object response, Stream stream)
    {
        var tasks = response as List<Task>;
        if (tasks != null)
        {
            using (var sw = new StreamWriter(stream))
            {
                if (tasks.Count == 0)
                {
                    sw.WriteLine("<Tasks/>");
                    return;
                }

                sw.WriteLine("<Tasks>");
                foreach (Task task in tasks)
                {
                    if (task != null)
                    {
                        sw.WriteLine("  <Task type=\"new serializer\">");
                        sw.Write("    <TaskName>");
                        sw.Write(task.TaskName);
                        sw.WriteLine("</TaskName>");
                        sw.Write("    <AuxData>");
                        sw.Write(task.AuxData);
                        sw.WriteLine("</AuxData>");
                        sw.WriteLine("  </Task>");
                    }
                }
                sw.WriteLine("</Tasks>");
            }
        }
        else
        {
            var task = response as Task;
            using (var sw = new StreamWriter(stream))
            {
                if (task != null)
                {
                    sw.WriteLine("  <Task type=\"new serializer\">");
                    sw.Write("    <TaskName>");
                    sw.Write(task.TaskName);
                    sw.WriteLine("</TaskName>");
                    sw.Write("    <AuxData>");
                    sw.Write(task.AuxData);
                    sw.WriteLine("</AuxData>");
                    sw.WriteLine("  </Task>");
                }
            }
        }
    }

    public static object DeserializeTaskFromStream(Type type, Stream stream)
    {
        if (stream == null || stream.Length == 0)
            return null; // should throw exception?
        XDocument xdoc = XDocument.Load(stream);
        XElement auxData = xdoc.Root.Element("AuxData");

        return new Task() { AuxData = auxData.Value };
    }


    public override bool Equals(object obj)
    {
        Task task = obj as Task;
        if (task == null)
            return false;
        return TaskName.Equals(task.TaskName);
    }

    public override int GetHashCode()
    {
        return TaskName.GetHashCode();
    }
}

J'ai basé mon code de sérialisation/désérialisation sur : http://www.servicestack.net/ServiceStack.Northwind/vcard-format.htm et https://github.com/ServiceStack/ServiceStack.Examples/blob/master/src/ServiceStack.Northwind/ServiceStack.Northwind.ServiceInterface/VCardFormat.cs

Ma classe de test de base est la suivante :

public class SimpleRestTestBase : AppHostBase
{
    public SimpleRestTestBase() : base( "SimpleRestTestBase", typeof(TaskService).Assembly)
    {
        Instance = null;
        Init();
    }

    public override void Configure(Funq.Container container)
    {
        SetConfig(new EndpointHostConfig
        {
            DefaultContentType = ContentType.Xml
        }
        );

        Task.RegisterCustomSerialization(this);

        Routes
          .Add<Task>("/tasks/{TaskName}")
          .Add<List<Task>>("/tasks");

        container.Register(new List<Task>());
    }
}

Et le test unitaire qui échoue :

[TestFixture]
public class SimpleTest : SimpleRestTestBase
{
    [Test]
    public void TestMetodRequiringServer()
    {
        var client = (IRestClient)new XmlServiceClient("http://localhost:53967");
        var data = client.Get<List<Task>>("/api/tasks");
    }
}

L'exception que j'obtiens lors de l'utilisation du lanceur de tests nUnit est :

Testing.SimpleTest.TestMetodRequiringServer: System.Runtime.Serialization.SerializationException : Error in line 1 position 9. Expecting element 'ArrayOfTask' from namespace 'http://schemas.datacontract.org/2004/07/ServiceStackMVC'.. Encountered 'Element' with name 'Tasks', namespace ''.

Comment transmettre des informations sur mon code de sérialisation/désialisation personnalisé au XmlServiceClient?

Était-ce utile?

La solution

Vous remplacez le format générique de sérialisation XML (application/xml) par une version personnalisée fortement couplée pour gérer uniquement 1 sortie de service Web - c'est très rarement ce que vous souhaitez car cela empêchera (c'est-à-direbreak) tous vos autres services de renvoyer du XML.Si vous souhaitez renvoyer du XML personnalisé, limitez-vous simplement aux services qui en ont besoin en renvoyant une chaîne XML à la place.

Vous ne pouvez pas modifier l'implémentation de XmlServiceClient car elle est fortement couplée à la sérialisation/désérialisation XML utilisée par ServiceStack.Vous devez utiliser un client HTTP brut pour envoyer la charge utile XML exacte souhaitée.Voici un exemple d'envoi de XML brut avec la requête Web .NET :https://stackoverflow.com/a/8046734/85785

Puisque vous renvoyez et envoyez du XML personnalisé, vous souhaiterez peut-être également remplacer le classeur de requêtes personnalisées pour votre service Web afin d'avoir la possibilité de désérialiser la requête comme vous le souhaitez.

Consultez la page wiki ci-dessous pour quelques exemples sur la façon de procéder :

https://github.com/ServiceStack/ServiceStack/wiki/Serialization-deserialization

Note:renvoyer du XML personnalisé n'est pas idéal car il contourne de nombreux avantages de la nature typée forte, intelligente et opiniâtre de ServiceStack.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top