사용자 정의 직렬화 / Deserialization을 사용한 유닛 테스트 서비스 서비스
-
12-12-2019 - |
문제
나는 자체 DE / 직렬화 메커니즘이 제공된 웹 서비스를 테스트하는 데 문제가 있습니다.
Task
에서 사용중인 샘플 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();
}
}
.
I : http : // www. servicestack.net/servicestack.northwind/vcard-format.htm 및 https://github.com/servicestack/servicestack.examples/blob/master/src/servicestack.northwind/servicestack.northwind.serviceintface/vcardformat.cs
내 기본 테스트 클래스는 다음과 같습니다.
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>());
}
}
.
및 실패한 단위 테스트 :
[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");
}
}
.
NUNIT 테스트 러너를 사용할 때 얻는 예외는 다음과 같습니다.
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 ''.
사용자 정의 직렬화 / 음성화 코드에 대한 정보를 XmlServiceClient
에 어떻게 전달합니까?
해결책
일반 XML 직렬화 형식 (Application / XML)을 Welly-Couply 1 웹 서비스 출력 만 처리 할 수있는 사용자 지정 버전으로 무시합니다. 이것은 매우 드뭅니다 (즉, 휴식을 취할 수 있습니다). XML을 반환하는 다른 서비스. 사용자 정의 XML을 반환하려면 XML 문자열을 대신 반환하여 필요한 서비스로 제한하십시오.
XMLServiceClient의 구현은 XML 직렬화 / servicestack이 사용하는 XML 직렬화 / deserialization에 크게 결합 될 때 변경할 수 없습니다. 원하는 XML 페이로드를 보내려면 원시 HTTP 클라이언트를 사용해야합니다. 다음은 .NET의 웹 요청으로 원시 XML을 보내는 예입니다. https://stackoverflow.com/a/8046734/85785
사용자 정의 XML을 반환하고 보내는 이래 웹 서비스에 대한 사용자 정의 요청 바인더를 무시할 수 있으므로 원하는 방식의 요청을 수행 할 수있는 기회가 있습니다.
이를 수행하는 방법에 대한 몇 가지 예제는 다음과 같은 Wiki 페이지를 참조하십시오.
https://github.com/servicestack/servicestack/wiki/serialization-deserialization.
참고 : 사용자 정의 XML을 반환하는 것은 서비스가 강한 타이핑되고 지능형이며 의견이있는 자연의 많은 이점을 지나치게합니다.