标签: mspec

如何在MSpec中的每个测试中运行设置和拆卸代码?

我有用于设置和拆除NHibernate的通用代码,我几乎所有的测试都需要它.有没有办法在一个地方包含"需要所有测试"代码,然后将其应用于所有测试?(比如Nunit setupteardown方法)

[Subject("Accessing the TAE allocation page")]
public class when_a_request_to_the_tae_allocation_page_is_made
{
    Establish context = () => NHTestHelper.StartTest(); //need for all tests

    Because of = () => result = new AllocationController(true).Index();

    It should_display_the_page = () => result.ShouldBeAView();

    Cleanup nh = () => NHTestHelper.EndTest(); //need for all tests

    static ActionResult result;
}
Run Code Online (Sandbox Code Playgroud)

.net nhibernate mspec

9
推荐指数
1
解决办法
2075
查看次数

如何为MSpec的所有接口实现编写通用测试?

我有IAudioProcessor一个单一方法的接口IEnumerable<Sample> Process(IEnumerable<Sample> samples).虽然它不是接口本身的要求,但我想确保我的所有实现遵循一些通用规则,例如:

  1. 使用延迟执行
  2. 请勿更改输入样本

为这些创建测试并不难,但我必须为每个实现复制并粘贴这些测试.我想避免这种情况.

我想做这样的事情(注意属性GenericTest和类型参数):

[GenericTest(typeof(AudioProcessorImpl1Factory))]
[GenericTest(typeof(AudioProcessorImpl2Factory))]
[GenericTest(typeof(AudioProcessorImpl3Factory))]
public class when_processed_audio_is_returned<TSutFactory>
    where TSutFactory : ISutFactory<IAudioProcessor>, new()
{
    static IAudioProcessor Sut = new TSutFactory().CreateSut();
    protected static Context _ = new Context();

    Establish context = () => _.Original = Substitute.For<IEnumerable<ISample>>();

    Because of = () => Sut.Process(_.Original);

    It should_not_have_enumerated_the_original_samples = () =>
    {
        _.Original.DidNotReceive().GetEnumerator();
        ((IEnumerable)_.Original).DidNotReceive().GetEnumerator();
    };
}
Run Code Online (Sandbox Code Playgroud)

这样的事情可能吗?

c# bdd unit-testing mspec

8
推荐指数
1
解决办法
766
查看次数

8
推荐指数
1
解决办法
361
查看次数

什么BDD框架在.net中很流行?

我最近进入BDD并认为它有很大的希望,作为一种方式,让我们作为开发人员为他们创建的应用程序中的利益相关者的声音.你最喜欢的BDD框架是什么?为什么?

.net bdd mspec nspec

7
推荐指数
3
解决办法
1891
查看次数

如何在MSpec中输出带有It断言的消息

之前使用过MbUnit,我们正在使用MSpec进行单元测试.

我习惯说

Assert.IsTrue(status, "Status should be true");
Run Code Online (Sandbox Code Playgroud)

在MbUnit中,即向断言添加消息,如果失败则输出该消息.

我在MSpec中找不到任何相应的功能.我正在测试一些XML验证,如果失败,我想报告验证错误消息.所以我的MSpec代码看起来像

string message;

bool isValid = ValidateXml(myXml, out message);

isValid.ShouldBeTrue();
Run Code Online (Sandbox Code Playgroud)

但是message如果ShouldBeTrue()失败,我希望能够将测试输出添加到测试输出中.

这可能吗?

unit-testing assert mspec

7
推荐指数
1
解决办法
569
查看次数

Moq的意外验证行为

在我的最新项目中,Moq让我有点疯狂.我最近升级到版本4.0.10827,我注意到在我看来是一个新的行为.

基本上,当我MakeCall在我正在测试的代码中调用我的模拟函数(在本例中)时,我传入一个object(TestClass).我正在测试的代码TestClass在调用之前和之后对对象进行了更改MakeCall.一旦代码完成,我就调用Moq的Verify功能.我的期望是,Moq将记录我传入的完整对象MakeCall,可能通过深度克隆等机制.通过这种方式,我将能够验证是否MakeCall使用我希望调用它的确切对象进行调用.不幸的是,这不是我所看到的.

我试图在下面的代码中说明这一点(希望在此过程中澄清一点).

  1. 我首先创建一个新TestClass对象.它的Var财产设置为"one".
  2. 然后我创建了模拟对象mockedObject,这是我的测试主题.
  3. 然后我调用MakeCall方法mockedObject(顺便说一下,示例中使用的Machine.Specifications框架允许When_Testing从上到下读取类中的代码).
  4. 然后我测试模拟对象,以确保它的确TestClass使用Var值为"one".正如我所预料的那样,这成功了.
  5. 然后我TestClass通过重新分配Var属性来更改原始对象"two".
  6. 然后我继续尝试验证Moq是否仍然认为使用值为的MakeCall调用.这失败了,虽然我期待它是真的. TestClass"one"
  7. 最后,我测试看看Moq是否认为MakeCall实际上是由TestClass具有值的对象调用的"two".这成功了,虽然我最初预计它会失败.

对我来说,似乎很清楚Moq只保留对原始TestClass对象的引用,允许我改变其值而不受惩罚,对我的测试结果产生不利影响.

关于测试代码的一些注意事项. IMyMockedInterface是我嘲笑的界面. TestClass是我传递给该MakeCall方法的类,因此用于演示我遇到的问题.最后,When_Testing是包含测试代码的实际测试类.它正在使用Machine.Specifications框架,这就是为什么有一些奇怪的项目('因为','它应该...').这些只是框架调用以执行测试的委托.如果需要,应该很容易删除它们并将包含的代码放入标准函数中.我把它留在这种格式中,因为它允许所有Validate调用完成(与'Arrange,Act Assert'范例相比).只是为了澄清,下面的代码不是我遇到问题的实际代码.它只是为了说明问题,因为我在多个地方看到了同样的行为.

using Machine.Specifications;
// …
Run Code Online (Sandbox Code Playgroud)

asp.net-mvc moq mspec

7
推荐指数
1
解决办法
383
查看次数

MSpec,我应该在我的[Subject()]属性中添加什么?

我一直在使用MSpec,我真的很喜欢它.我发现要让ReSharper识别我的规格,我需要使用SubjectAttribute.

我想知道,在[Subject()]属性中放入什么是最好的东西?

如果我正在做BDD,那么我不知道被测试的类型所以[Subject(typeof(thingy))]似乎为时过早.可以在以后添加,我想一旦编写代码.

所以留下文本版本,[Subject("some text")].但放在那里最好的是什么?

无论我做什么,它似乎都不会影响我在ReSharper中获得的输出.我想在某种程度上这取决于个人偏好,但我想知道这里是否有任何约定?

tdd bdd mspec

7
推荐指数
1
解决办法
927
查看次数

为什么不调用我的Equals方法?

我正在通过Kent Beck的TDD作为学术练习,但是使用MSpec来编写测试.在下面的工作示例中,我想介绍一个扭曲,以便我不能简单地将文本复制出来,我发现这种方式我倾向于遇到我必须解决的问题,因此,最终学习更多.我相信这是其中一个场合.

我通过肯特的"钱"例子.这是我的类结构: 在此输入图像描述

我有以下两个测试环境:

[Subject(typeof(Money), "Equality")]
public class when_comparing_different_classes_for_equality
{
    Because of = () => FiveFrancs = new Franc(5, "CHF");
    It should_equal_money_with_currency_set_to_francs = () => FiveFrancs.Equals(new Money(5, "CHF")).ShouldBeTrue();
    static Franc FiveFrancs;
}

[Subject(typeof(Franc), "multiplication")]
public class when_multiplying_a_franc_amount_by_an_integer
{
    Because of = () => FiveFrancs = new Franc(5, null);
    It should_be_ten_francs_when_multiplied_by_2 = () => FiveFrancs.Times(2).ShouldEqual(Money.Franc(10));
    It should_be_fifteen_francs_when_multiplied_by_3 = () => FiveFrancs.Times(3).ShouldEqual(Money.Franc(15));
    static Franc FiveFrancs;
}
Run Code Online (Sandbox Code Playgroud)

Times()方法返回一个包含结果的Money类型的新对象,即对象是不可变的.上面的第一个上下文传递,表明Equals正在按预期工作,即它忽略了对象类型,只要它们都是从Money继承的,并且只比较金额和货币字段是相等的.第二个上下文失败,输出类似于:

Machine.Specifications.SpecificationException
  Expected: TDDByExample.Money.Specifications.Franc:[15]
  But was:  TDDByExample.Money.Specifications.Money:[15]
   at TDDByExample.Money.Specifications.when_multiplying_a_franc_amount_by_an_integer.<.ctor>b__2() in MoneySpecs.cs: line 29
Run Code Online (Sandbox Code Playgroud)

平等定义为金额(价值)和货币相同; 应该忽略对象的实际类型,因此预期的结果是,如果我正在测试与Money或Franc对象的相等性,只要金额和货币字段相同,则无关紧要.但是,事情没有按计划进行.调试时,我的Equals()方法甚至没有被调用.显然我在这里并不理解.我确信当我知道它时,解决方案将会非常明显,但我看不出它.任何人都可以提出一个建议,我需要做些什么来使这项工作?

这是Equals()的实现: …

c# tdd mspec

7
推荐指数
1
解决办法
276
查看次数

FakeItEasy代理方法调用实际实现

我正在尝试将对虚假对象的调用代理到实际实现.这样做的原因是我希望能够使用Machine.Specifications的WasToldTo和WhenToldTo,它仅适用于接口类型的伪造.

因此,我正在执行以下操作来代理对我的真实对象的所有调用.

public static TFake Proxy<TFake, TInstance>(TFake fake, TInstance instance) where TInstance : TFake
{
    fake.Configure().AnyCall().Invokes(x => x.Method.Invoke(instance, x.Arguments.ToArray()));
    return fake;
}
Run Code Online (Sandbox Code Playgroud)

我会像这样使用它.

var fake = Proxy<ISomeInterface, SomeImplementation>(A.Fake<ISomeInterface>(), new SomeImplementation());

//in my assertions using Machine.Specifications (reason I need a fake of an interface)
fake.WasToldTo(x => x.DoOperation());
Run Code Online (Sandbox Code Playgroud)

然而问题是这只适用于void方法,因为Invokes方法没有对返回值做任何事情.(Action param代替Func)

然后我尝试使用WithReturnValue方法执行此操作.

public static TFake Proxy(TFake fake, TInstance instance) where TInstance : TFake
{
    fake.Configure().AnyCall()..WithReturnType().Invokes(x => x.Method.Invoke(instance, x.Arguments.ToArray()));
    fake.Configure().AnyCall()..WithReturnType().Invokes(x => x.Method.Invoke(instance, x.Arguments.ToArray()));
    fake.Configure().AnyCall()..WithReturnType().Invokes(x => x.Method.Invoke(instance, x.Arguments.ToArray()));
    //etc.
    return fake;
}
Run Code Online (Sandbox Code Playgroud)

然而,Invokes方法仍然不能按我想要的方式工作(仍然是Action而不是Func).所以仍然没有使用返回值.

有没有办法用当前的最新版本实现这一目标?

我已经在FakeItEasy …

c# unit-testing mocking mspec fakeiteasy

7
推荐指数
1
解决办法
1966
查看次数

MSpec是否支持"行测试"或数据驱动测试,如NUnit TestCase?

我们使用Machine.Specification作为我当前项目的测试框架.这适用于我们测试的大部分内容.但是,我们有许多视图模型,其中我们具有"格式化"属性,这些属性采用一些原始数据,应用一些逻辑,并返回该数据的格式化版本.

由于格式化涉及逻辑(空检查,零特殊情况等),我想测试一些可能的数据值,包括边界条件.对我来说,这不是MSpec的正确用例,我们应该深入到像NUnit这样的东西,我可以使用类似[TestCase]属性的东西来编写数据驱动的测试.

有没有一种干净,简单的方法在MSpec中编写这种测试,或者我觉得我们应该使用不同的工具进行这种测试?

查看模型

public class DwellingInformation
{        
    public DateTime? PurchaseDate { get; set; }
    public string PurchaseDateFormatted
    {
        if(PurchaseDate == null)
            return "N/A";

        return PurchaseDate.Value.ToShortDateString();
    }

    public int? ReplacementCost { get; set; }
    public string ReplacementCostFormatted
    {
        if(ReplacementCost == null)
            return "N/A";

        if(ReplacementCost == 0)
            return "Not Set";

        return ReplacementCost.ToString("C0");
    }

    // ... and so on...
}
Run Code Online (Sandbox Code Playgroud)

MSpec测试

public class When_ReplacementCost_is_null
{
    private static DwellingInformation information;

    Establish context = () =>
    {
        information = new DwellingInformation { ReplacementCost = …
Run Code Online (Sandbox Code Playgroud)

c# unit-testing mspec

7
推荐指数
1
解决办法
453
查看次数