ServiceStack:如何对提供文件的服务进行单元测试

时间:2017-09-21 05:42:20

标签: c# web-services unit-testing servicestack servicestack-text

我有一个为Excel文件提供服务的网络服务

public class ReportService : Service
{
    public IReportRepository Repository {get; set;}

    public object Get(GetInvoiceReport request)
    {
        var invoices = Repository.GetInvoices();

        ExcelReport report = new ExcelReport();
        byte[] bytes = report.Generate(invoices);

        return new FileResult(bytes);
    }
}

我设置了从服务中退回的对象

public class FileResult : IHasOptions, IStreamWriter, IDisposable
{
    private readonly Stream _responseStream;
    public IDictionary<string, string> Options { get; private set; }

    public BinaryFileResult(byte[] data)
    {
        _responseStream = new MemoryStream(data);

        Options = new Dictionary<string, string>
        {
            {"Content-Type", "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"},
            {"Content-Disposition", "attachment; filename=\"InvoiceFile.xlsx\";"}
        };
    }

    public void WriteTo(Stream responseStream)
    {
        if (_responseStream == null)
            return;

        using (_responseStream)
        {
            _responseStream.WriteTo(responseStream);
            responseStream.Flush();
        }
    }

    public void Dispose()
    {
        _responseStream.Close();
        _responseStream.Dispose();
    }
}

现在,通过浏览器测试时,web服务工作正常;但是从单元测试中测试时会出现错误消息。以下是错误消息:

  

System.Runtime.Serialization.SerializationException:类型定义   应该以'{'开头,期待序列化类型'FileResult',得到   字符串开头:   PK \ U0003 \ U0004 \ u0014 \ u0000的\ u0008 \ u0000的\ u0008 \ u0000的\ u000b5K%\ U0001 \ u0000的\ u0000的\ U0003 \ u0000的\ u0000的\ u0013 \ u0000的\ u0000的\ u0000的[CONTENT_TYPES] .XML   在   ServiceStack.Text.Common.DeserializeTypeRefJson.StringToType(TypeConfig   typeConfig,StringSegment strType,EmptyCtorDelegate ctorFn,   字典2 typeAccessorMap) at ServiceStack.Text.Common.DeserializeType 1.&lt;&gt; c__DisplayClass2_0.b__1(StringSegment值)在ServiceStack.Text.Json.JsonReader 1.Parse(StringSegment value) at ServiceStack.Text.Json.JsonReader 1.Parse(String value)
  at ServiceStack.Text.JsonSerializer.DeserializeFromString [T](String   价值)   ServiceStack.Text.JsonSerializer.DeserializeFromStream [T](流   流)   ServiceStack.ServiceClientBase.GetResponse [τ响应(WebResponse的   webResponse)在   ServiceStack.ServiceClientBase.Send [TResponse](String httpMethod,   String relativeOrAbsoluteUrl,Object request)

以下是我用来测试网络服务的单元测试:

[Test]
public void TestInvoiceReport()
{
    var client = new JsonServiceClient("http://localhost/report/");

    var authResponse = client.Send(new Authenticate
                {
                    provider = CredentialsAuthProvider.Name,
                    UserName = "[User Name]",
                    Password = "[Password]"
                }); 

    var requestDTO = new GetInvoiceReport();

    var ret = client.Get<FileResult>(requestDTO);

    Assert.IsTrue(ret != null);
}

修改 我包括我的请求DTO类的定义:

[Route("/invoices", "GET")]
public class GetInvoiceReport: IReturn<FileResult>
{

}

感谢任何帮助。

1 个答案:

答案 0 :(得分:2)

注意:如果您正在制作HTTP请求而不是在代码中调用服务,则它是Integration Test而不是单元测试。

您尚未提供GetInvoiceReport请求DTO定义,但如果您返回的不是序列化DTO的任何内容,则应将其指定为IReturn<T>接口,例如:

public class GetInvoiceReport : IReturn<byte[]> { ... }

然后您可以使用以下命令下载原始字节:

byte[] response = client.Get(new GetInvoiceReport());

您可以使用服务客户端请求筛选器来检查HTTP响应标头。

我还建议您查看ServiceStack的.NET服务客户端文档,其中包含downloading raw Responses的详细信息。