标签: autofixture

MOQ和AutoFixture有什么区别?

我有很多使用MOQ的经验,而我最近偶然发现了AutoFixture.这些框架之间有什么区别?

unit-testing moq mocking autofixture automocking

12
推荐指数
1
解决办法
3085
查看次数

为类型创建AutoFixture样本构建器

在这种情况下,我正在为特定类型创建一个AutoFixture样本构建器System.Data.DataSet.构建器将返回a FakeDataSet,这是DataSet为测试而定制的.

以下不起作用,dataSet总是返回null,即使DataSet正在请求a(我可以通过钻取request属性来判断).

public class DataSetBuilder : ISpecimenBuilder
{
    public object Create(object request, ISpecimenContext context)
    {
        var dataSet = request as DataSet;
        if (dataSet == null)
        {
            return new NoSpecimen(request);
        }

        return new FakeDataSet();
    }
}
Run Code Online (Sandbox Code Playgroud)

这种变化确实有效,但似乎过于复杂.感觉有更好的方法来完成同样的事情,我只是缺少一些东西.

public class DataSetBuilder : ISpecimenBuilder
{
    public object Create(object request, ISpecimenContext context)
    {
        var seededRequest = request as SeededRequest;
        if (seededRequest == null)
        {
            return new NoSpecimen(request);
        }

        var requestType = seededRequest.Request …
Run Code Online (Sandbox Code Playgroud)

c# autofixture

12
推荐指数
1
解决办法
2853
查看次数

将DRY应用于自动混合"构建"语句

假设我有这个具体的类:

public partial class User
{
    public int ID { get; set; }
    public string Email { get; set; }
    public string FullName { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

我想创建一个具有有效电子邮件地址的匿名实例,并且fullname字段不超过20个字符.我可以做这个:

var fixture = new Fixture();
var anonUser = fixture.Build<User>()
    .With(x => x.Email, string.Format("{0}@fobar.com", fixture.Create<string>()))
    .With(x => x.FullName,  fixture.Create<string>()Substring(0,20))
    .Create();
Run Code Online (Sandbox Code Playgroud)

有没有办法可以在一个地方定义它,所以AF知道我可以通过使用以下方式获得我的自定义anon类:

var newAnon = fixture.Build<User>();
Run Code Online (Sandbox Code Playgroud)

c# autofixture

12
推荐指数
1
解决办法
1427
查看次数

如何告诉AutoFixture在实例化TBase时始终创建TDerived?

我有一个深度嵌套的对象模型,其中一些类可能看起来像这样:

class TBase { ... }

class TDerived : TBase { ... }

class Container
{
    ICollection<TBase> instances;
    ...
}

class TopLevel
{
    Container container1;
    Container container2;
    ...
}
Run Code Online (Sandbox Code Playgroud)

我想将我的顶级对象创建为测试夹具,但我希望所有TBase实例(例如instances上面的集合中)都是实例TDerived而不是TBase.

我以为我可以简单地使用以下内容来做到这一点:

var fixture = new Fixture();

fixture.Customize<TBase>(c => c.Create<TDerived>());

var model = this.fixture.Create<TopLevel>();
Run Code Online (Sandbox Code Playgroud)

...但是这不起作用,因为lambda表达式Customize是错误的.我猜测有一种方法可以做到这一点,但AutoFixture似乎缺乏文档,而不是开发人员博客上的意识流.

谁能指出我正确的方向?

c# autofixture

12
推荐指数
2
解决办法
707
查看次数

如何使用仅在返回类型上重载的两个属性发出.NET类型?

我需要创建一个具有两个具有相同名称的属性的类型,并且只在返回类型上有所不同.通过反射动态发射这种类型是完全可以接受的.

像这样的东西:

public TypeA Prop { get; }
public TypeB Prop { get; }
Run Code Online (Sandbox Code Playgroud)

我知道我不能从C#或VB.NET或许多其他.NET语言中使用这个属性.

为了防止答案向我解释为什么我不想这样做,让我解释一下为什么我需要它:我需要它来重现一个bug.

更具体地说,我在AutoFixture中有一个错误,其中一个类型的Moq会导致它在某些情况下抛出异常.问题是Moq发出的类型包含两个名为'Mock'的属性,它们仅在返回类型上有所不同.

我想在单元测试中重现这个场景,但是我不想仅仅因为这个原因而依赖于Moq,所以我想在测试套件内部重现这种行为.

.net moq autofixture

11
推荐指数
1
解决办法
255
查看次数

单元测试中的重复代码

我们发现自己在许多测试用例中编写重复的夹具/模拟设置 - 就像这种情况:

var fixture = new Fixture().Customize(new AutoMoqCustomization());
var encodingMock = fixture.Freeze<Mock<IEncodingWrapper>>();
var httpClientMock = fixture.Freeze<Mock<IHttpWebClientWrapper>>();
var httpResponseMock = fixture.Freeze<Mock<IHttpWebResponseWrapper>>();
var httpHeaderMock = fixture.Freeze<Mock<IHttpHeaderCollectionWrapper>>();
var etag = fixture.CreateAnonymous<string>();
byte[] data = fixture.CreateAnonymous<byte[]>();
Stream stream =  new MemoryStream(data);

encodingMock.Setup(m => m.GetBytes(It.IsAny<string>())).Returns(data);
httpHeaderMock.SetupGet(m => m[It.IsAny<string>()]).Returns(etag).Verifiable();
httpClientMock.Setup(m => m.GetResponse()).Returns(httpResponseMock.Object);
httpResponseMock.Setup(m => m.StatusCode).Returns(HttpStatusCode.OK);
httpResponseMock.SetupGet(m => m.Headers).Returns(httpHeaderMock.Object);
httpResponseMock.Setup(m => m.GetResponseStream()).Returns(stream);
Run Code Online (Sandbox Code Playgroud)

根据测试应该是自包含的并且从头到尾可读的想法,我们不使用神奇的Setup/Teardown方法.

我们可以以任何方式(AutoFixture自定义,辅助方法)减少这些测试的"笨拙的工作"吗?

c# nunit unit-testing moq autofixture

11
推荐指数
2
解决办法
1955
查看次数

AutoFixture/AutoMoq忽略注入的实例/冻结模拟

现在找到解决方案的简短内容:

AutoFixture返回冻结模拟就好了; 我的sut也是由AutoFixture生成的,只有一个公共属性,其本地默认值对于测试非常重要,并且AutoFixture设置为新值.除了Mark的答案之外,还有很多值得学习的东西.

原始问题:

我昨天开始尝试使用AutoFixture进行我的xUnit.net测试,这些测试中包含了Moq.我希望更换一些Moq的东西或者让它更容易阅读,我特别感兴趣的是在SUT工厂容量中使用AutoFixture.

我使用Mark Seemann的一些关于AutoMocking的博客文章,并尝试从那里开始工作,但我没有走得太远.

这是我的测试看起来没有AutoFixture:

[Fact]
public void GetXml_ReturnsCorrectXElement()
{
    // Arrange
    string xmlString = @"
        <mappings>
            <mapping source='gcnm_loan_amount_min' target='gcnm_loan_amount_min_usd' />
            <mapping source='gcnm_loan_amount_max' target='gcnm_loan_amount_max_usd' />
        </mappings>";

    string settingKey = "gcCreditApplicationUsdFieldMappings";

    Mock<ISettings> settingsMock = new Mock<ISettings>();
    settingsMock.Setup(s => s.Get(settingKey)).Returns(xmlString);
    ISettings settings = settingsMock.Object;

    ITracingService tracing = new Mock<ITracingService>().Object;

    XElement expectedXml = XElement.Parse(xmlString);

    IMappingXml sut = new SettingMappingXml(settings, tracing);

    // Act
    XElement actualXml = sut.GetXml();

    // Assert
    Assert.True(XNode.DeepEquals(expectedXml, actualXml));
}
Run Code Online (Sandbox Code Playgroud)

这里的故事很简单 - 确保使用正确的密钥(这是硬编码/属性注入)SettingMappingXml查询ISettings依赖关系并将结果返回为XElement.在 …

c# unit-testing autofixture automocking

11
推荐指数
1
解决办法
3719
查看次数

从所有值的子集创建匿名枚举值

假设我们将枚举类型定义为:

enum Statuses
{
    Completed,
    Pending,
    NotStarted,
    Started
}
Run Code Online (Sandbox Code Playgroud)

我想让Autofixture为我创造一个价值,而不是像Pending.

所以(假设循环生成)我想获得:

已完成,未启动,已启动,已完成,未启动,...

c# autofixture

11
推荐指数
1
解决办法
3155
查看次数

如何让AutoFixture创建一个> 0的整数,而不是另一个数字?

我希望AutoFixture生成两个整数,而对于第二个整数,我不希望它为0或先前生成的数字.有没有办法告诉AutoFixture尊重"要求".

RandomNumericSequenceGenerator,我看起来下限是1,所以我可能不必指定第一个要求.接下来,我正在查看"种子"选项,但正如此答案中所示,默认情况下它不会用于数字.

有什么东西我在这里俯瞰吗?

c# random int autofixture

11
推荐指数
1
解决办法
5526
查看次数

自动修复和只读属性

让我们考虑同一个非常简单的实体的两个版本(一个带有只读属性):

public class Client
{
    public Guid Id { get; set; }

    public string Name { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

public class Client
{
    public Client(Guid id, string name)
    {
        this.Id = id;
        this.Name = name;
    }

    public Guid Id { get; }

    public string Name { get; }
}
Run Code Online (Sandbox Code Playgroud)

当我尝试使用Autofixture时,它们将正常工作,并且可以同时使用它们。当我尝试使用预先定义参数之一时,问题就开始了。with()方法:

var obj = this.fixture.Build<Client>().With(c => c.Name, "TEST").Build();
Run Code Online (Sandbox Code Playgroud)

这将引发错误

System.ArgumentException:属性“名称”是只读的。

但是似乎Autofixture知道如何使用构造函数!而且看来实际Build<>()方法不是创建对象的实例Create()!如果构建仅准备具有设置属性的构建器,然后创建将实例化对象,则它将与只读属性一起正常工作。

那么为什么在这里使用这种(误导)策略呢?我在这里找到了一个答案,指出它是通过测试来放大反馈,但是我看不出使用的用处,FromFactory()尤其是当参数列表很广时。在Build()方法之间移动对象实例化Create()会更直观吗?

c# readonly-attribute autofixture

11
推荐指数
2
解决办法
2562
查看次数