public override Task WriteToStreamAsync(Type type, object value, Stream stream, HttpContent content, TransportContext transportContext)
{
//go lookup the concrete for the interface
var newType = GetNewType(type);
var newValue = GetNewValue(value, type);
var serializer = new XmlSerializer(newType);
return Task.Factory.StartNew(() =>
{
using (var streamWriter = new StreamWriter(stream, _encoder))
{
var ns = new XmlSerializerNamespaces();
ns.Add("", "");
serializer.Serialize(streamWriter, newValue, ns);
}
});
}
此Custom mediatype格式化程序正在尝试序列化xml的命名空间。我试图测试这个方法,但抛出一个错误,无法访问一个封闭的流。有没有办法对这种方法进行单元测试。
答案 0 :(得分:1)
创建序列化程序的抽象
public interface ISerializer
{
void Serialize(StreamWriter writer, object value, XmlSerializerNamespaces ns);
}
然后使用构造函数注入向ISerializer
的实现注入MediaTypeFormatter
(感谢@pep指出)。这使您可以传递虚拟实现。
public class MyMediaTypeFormatter : MediaTypeFormatter
{
private ISerializer _serializer;
public MyMediaTypeFormatter(ISerializer serializer)
{
_serializer = serializer;
}
...
}
WriteToStreamAsync
然后只使用_serializer
:
public override Task WriteToStreamAsync(Type type, object value, Stream stream, HttpContent content, TransportContext transportContext)
{
var newType = GetNewType(type);
var newValue = GetNewValue(value, type);
return Task.Factory.StartNew(() => {
using (var streamWriter = new StreamWriter(stream, _encoder)) {
var ns = new XmlSerializerNamespaces();
ns.Add("", "");
_serializer.Serialize(streamWriter, newValue, ns);
}
});
}
可能的实施:
public class MyXmlSerializer<T> : ISerializer
{
private readonly XmlSerializer _xmlSerializer = new XmlSerializer(typeof(T));
public void Serialize(StreamWriter writer, object value, XmlSerializerNamespaces ns)
{
_xmlSerializer.Serialize(writer, value, ns);
}
}
可能的假人:
public class DummySerializer : ISerializer
{
// You can test these properties in the unit test after the call;
public StreamWriter Writer { get; private set; }
public object Value { get; private set; }
public XmlSerializerNamespaces NS { get; private set; }
public int Calls { get; private set; }
public void Serialize(StreamWriter writer, object value, XmlSerializerNamespaces ns)
{
Writer = writer;
Value = value;
NS = ns;
Calls++;
}
}
或使用NSubstitute或其他模拟框架。注意:这些框架会在运行时自动创建接口的虚拟实现。
针对接口而不是具体类进行编程不仅增加了代码的灵活性,而且通常也是单元测试的必需条件。
答案 1 :(得分:0)
您是否先尝试打开流然后再使用它?因为除非打开它,否则无法写入文件或从中读取文件。希望这有帮助! :)