首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何使用MSTest/xUnit框架编写上下文/规范样式的单元测试?

如何使用MSTest/xUnit框架编写上下文/规范样式的单元测试?
EN

Stack Overflow用户
提问于 2011-01-13 18:13:55
回答 5查看 8.2K关注 0票数 23

我一直使用MSpec来编写我的单元测试,我真的更喜欢BDD风格,我认为它更具可读性。我现在使用的是MSpec不支持的Silverlight,所以我不得不使用MSTest,但我仍然希望保持一种BDD风格,所以我正在尝试找到一种方法来做到这一点。

为了解释我想要获得的东西,下面是我如何编写MSpec测试的

代码语言:javascript
复制
[Subject(typeof(Calculator))]    
public class when_I_add_two_numbers : with_calculator
{
  Establish context = () => this.Calculator = new Calculator();
  Because I_add_2_and_4 = () => this.Calculator.Add(2).Add(4);
  It should_display_6 = () => this.Calculator.Result.ShouldEqual(6);
}

public class with_calculator
{
  protected static Calculator;
}

因此,使用MSTest,我会尝试这样编写测试(虽然您可以看到它不会工作,因为我已经添加了两个TestInitialize属性,但是您知道我想要做什么了。)

代码语言:javascript
复制
[TestClass]
public class when_I_add_two_numbers : with_calculator
{
   [TestInitialize]
   public void GivenIHaveACalculator()
   {
      this.Calculator = new Calculator();
   }

   [TestInitialize]
   public void WhenIAdd2And4()
   {
      this.Calculator.Add(2).Add(4);
   }

   [TestMethod]
   public void ThenItShouldDisplay6()
   {
      this.Calculator.Result.ShouldEqual(6);
   }
}

public class with_calculator
{
  protected Calculator Calculator {get;set;}
}

有没有人能想出一些更优雅的建议,用MSTest以这种方式编写测试?

EN

回答 5

Stack Overflow用户

回答已采纳

发布于 2011-01-13 18:41:31

你对这个有什么看法:

代码语言:javascript
复制
[TestClass]
public class when_i_add_two_numbers : with_calculator
{
    public override void When()
    {
        this.calc.Add(2, 4);
    }

    [TestMethod]
    public void ThenItShouldDisplay6()
    {
        Assert.AreEqual(6, this.calc.Result);
    }

    [TestMethod]
    public void ThenTheCalculatorShouldNotBeNull()
    {
        Assert.IsNotNull(this.calc);
    }
}

public abstract class with_calculator : SpecificationContext
{
    protected Calculator calc;

    public override void Given()
    {
        this.calc = new Calculator();
    }
}

public abstract class SpecificationContext
{
    [TestInitialize]
    public void Init()
    {
        this.Given();
        this.When();
    }

    public virtual void Given(){}
    public virtual void When(){}
}

public class Calculator
{
    public int Result { get; private set; }
    public void Add(int p, int p_2)
    {
        this.Result = p + p_2;
    }
}
票数 35
EN

Stack Overflow用户

发布于 2012-08-03 04:32:44

Mark Nijhof在他的Fohjin.DDD github repository中有使用NUnit进行给定-当-然后风格测试的an example

下面是上面引用的示例的摘录:

代码语言:javascript
复制
public class When_registering_an_domain_event : BaseTestFixture<PreProcessor>
{
    /* ... */

    protected override void When()
    {
        SubjectUnderTest.RegisterForPreProcessing<ClientMovedEvent>();
        SubjectUnderTest.Process();
    }

    [Then]
    public void Then_the_event_processors_for_client_moved_event_will_be_registered()
    {
        IEnumerable<EventProcessor> eventProcessors;
        EventProcessorCache.TryGetEventProcessorsFor(typeof(ClientMovedEvent), out eventProcessors);
        eventProcessors.Count().WillBe(1);
    }
}

您可以在base class implementation中看到给定的

代码语言:javascript
复制
[Given]
public void Setup()
{
    CaughtException = new NoExceptionWasThrownException();
    Given();

    try
    {
        When();
    }
    catch (Exception exception)
    {
        CaughtException = exception;
    }
    finally
    {
        Finally();
    }
}
票数 2
EN

Stack Overflow用户

发布于 2013-04-10 08:31:45

不过,我最近经常问这样的问题。有很多合理的选择,你可以很容易地创建自己的选择,如本文中的一些答案所示。我一直在开发一个BDD测试框架,目的是让它很容易扩展到任何单元测试框架。我目前支持MSTest和NUnit。它叫做Given,而且是开源的。它的基本思想非常简单,因为它为公共功能集提供了包装器,然后可以为每个测试运行器实现这些包装器。

以下是给定测试的NUnit示例:

代码语言:javascript
复制
[Story(AsA = "car manufacturer",
       IWant = "a factory that makes the right cars",
       SoThat = "I can make money")]
public class when_building_a_toyota : Specification
{
    static CarFactory _factory;
    static Car _car;

    given a_car_factory = () =>
                              {
                                  _factory = new CarFactory();
                              };

    when building_a_toyota = () => _car = _factory.Make(CarType.Toyota);

    [then]
    public void it_should_create_a_car()
    {
        _car.ShouldNotBeNull();
    }

    [then]
    public void it_should_be_the_right_type_of_car()
    {
        _car.Type.ShouldEqual(CarType.Toyota);
    }
}

我尽力忠实于Dan North's Introducting BDD博客中的概念,因此,所有的事情都是使用给定的、当的、然后的规范风格来完成的。它的实现方式允许你有多个赋值,甚至多个何时,它们应该按顺序执行(仍在检查这一点)。

此外,还有一套完整的应该扩展直接包含在给定中。这使得类似于上面看到的ShouldEqual()调用,但充满了用于集合比较和类型比较等的很好的方法。对于熟悉MSpec的人,我基本上去掉了它们,并做了一些修改,使它们在MSpec之外工作。

不过,我认为,回报在于报道。测试运行器充满了您创建的场景,因此您可以一目了然地了解每个测试实际在做什么,而无需深入研究代码:

此外,基于每个程序集的测试结果,使用t4模板创建一个HTML报告。具有匹配故事的类都嵌套在一起,并且打印每个场景名称以供快速参考。对于上述测试,报告将如下所示:

失败的测试将显示为红色,可以单击查看异常详细信息。

差不多就是这样。我在几个我正在做的项目中使用它,所以它仍在积极开发中,但我认为它的核心相当稳定。我正在寻找一种通过组合而不是继承来共享上下文的方法,因此这可能是下一步的变化之一。带来批评。:)

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/4678882

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档