3

我正在使用 MEF 编写自定义语言着色器作为 Visual Studio 扩展。我的大部分代码都来自于此处提供的 Ook 语言集成示例。我的着色器已经准备就绪,但现在我需要为我的实现提供一个合适的单元测试套件。

鉴于这些东西的 MEF 特性,我想知道哪种方法适合进行单元测试。我应该直接从单元测试中引用我的标记器并测试 GetTags 方法吗?我应该让 MEF 参与我的单元测试吗?有没有关于测试基于 MEF 的着色器和自定义 Intellisense 实现的示例?

4

1 回答 1

2

好的,所以我想我有办法做到这一点。不知道这是否是理想的方法,但允许我测试我的核心逻辑。功劳归于Visual Studio 的 HQL 语言服务背后的人,他们向我展示了如何为 ITextSnapshots 创建存根,以及Noah RichardsSpell 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 编辑器扩展的人有用。

于 2011-10-07T12:50:35.800 回答