我正在使用 MEF 编写自定义语言着色器作为 Visual Studio 扩展。我的大部分代码都来自于此处提供的 Ook 语言集成示例。我的着色器已经准备就绪,但现在我需要为我的实现提供一个合适的单元测试套件。
鉴于这些东西的 MEF 特性,我想知道哪种方法适合进行单元测试。我应该直接从单元测试中引用我的标记器并测试 GetTags 方法吗?我应该让 MEF 参与我的单元测试吗?有没有关于测试基于 MEF 的着色器和自定义 Intellisense 实现的示例?
我正在使用 MEF 编写自定义语言着色器作为 Visual Studio 扩展。我的大部分代码都来自于此处提供的 Ook 语言集成示例。我的着色器已经准备就绪,但现在我需要为我的实现提供一个合适的单元测试套件。
鉴于这些东西的 MEF 特性,我想知道哪种方法适合进行单元测试。我应该直接从单元测试中引用我的标记器并测试 GetTags 方法吗?我应该让 MEF 参与我的单元测试吗?有没有关于测试基于 MEF 的着色器和自定义 Intellisense 实现的示例?
好的,所以我想我有办法做到这一点。不知道这是否是理想的方法,但允许我测试我的核心逻辑。功劳归于Visual Studio 的 HQL 语言服务背后的人,他们向我展示了如何为 ITextSnapshots 创建存根,以及Noah Richards的Spell Checker 扩展具有一组单元测试,这些单元测试为我的测试设置了场景。
这是我的 TestFixture 的代码:
[TestFixture]
public class TokenTaggerTests
{
[Test]
public void CanGetTagsForSimpleSelect()
{
TestQuery("SELECT * FROM Books", new List<string>() { "SELECT", "*", "FROM", "Books"});
}
private void TestQuery(string query, List<string> expected)
{
ITextSnapshot snapshot = SnapshotUtil.CreateSnapshot(query);
NormalizedSnapshotSpanCollection spans = new NormalizedSnapshotSpanCollection(snapshot.CreateSpanFromLineNumber(0));
MyTokenTagProvider provider = new MyTokenTagProvider();
ITagger<ITag> tagger = provider.CreateTagger<ITag>(new Mock<ITextBuffer>().Object);
List<string> words = tagger.GetTags(spans).Select(s => query.Substring(s.Span.Start, s.Span.Length)).ToList();
string errorMessage = string.Format("Got list: [{0}]. Expected: [{1}]", string.Join(", ", words), string.Join(", ", expected));
CollectionAssert.AreEqual(expected, words, errorMessage);
}
}
在 TestQuery 方法中,我首先在 SnapshotUtil 上调用 CreateSnapshot。这是一个有用的类,可以在 HQL 语言服务测试项目中找到,它会根据一些输入文本创建 ITextSnapshot 对象,模拟 VS 将提供给我的扩展的内容。然后我去使用 MyTokenTagProvider 为我创建一个标记器。这里我使用这个强大的东西叫做Moq来创建一个 ITextBuffer 对象的 Mock,这是 CreateTagger 的预期输入参数。
现在我们有了一个标注器,剩下的只是玩弄它来检查它是否在做这项工作。GetTags 是我想在这里测试的核心方法,因为它将接受我的输入查询并输出它能够识别的一系列标签。为了获得实际的单词,我们检查每个标签的跨度并使用它从原始查询中提取单词。NUnit 的 CollectionAssert 方法将确保输出的单词列表与预期的列表匹配。
希望这对其他创建和测试 VS 编辑器扩展的人有用。