标签: autofixture

单元测试中的重复代码

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

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
查看次数

自动修复和只读属性

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

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
查看次数

AutoFixture重构

我开始使用AutoFixture http://autofixture.codeplex.com/,因为我的单元测试因大量数据设置而膨胀.我花费更多时间来设置数据而不是编写单元测试.这是我的初始单元测试的样子的例子(例子来自DDD蓝皮书的货物申请样本)

[Test]
public void should_create_instance_with_correct_ctor_parameters()
{
    var carrierMovements = new List<CarrierMovement>();

    var deparureUnLocode1 = new UnLocode("AB44D");
    var departureLocation1 = new Location(deparureUnLocode1, "HAMBOURG");
    var arrivalUnLocode1 = new UnLocode("XX44D");
    var arrivalLocation1 = new Location(arrivalUnLocode1, "TUNIS");
    var departureDate1 = new DateTime(2010, 3, 15);
    var arrivalDate1 = new DateTime(2010, 5, 12);

    var carrierMovement1 = new CarrierMovement(departureLocation1, arrivalLocation1, departureDate1, arrivalDate1);

    var deparureUnLocode2 = new UnLocode("CXRET");
    var departureLocation2 = new Location(deparureUnLocode2, "GDANSK");
    var arrivalUnLocode2 = new UnLocode("ZEZD4");
    var arrivalLocation2 = new Location(arrivalUnLocode2, "LE HAVRE"); …
Run Code Online (Sandbox Code Playgroud)

c# unit-testing autofixture

10
推荐指数
1
解决办法
1619
查看次数

此测试是否正确使用AutoFixture和Moq?

此测试是否正确使用AutoFixture和Moq?它是尽可能简明扼要地写的吗?正如预期的那样,测试失败,并在写完正确的实现后通过.

[Fact]
public void CustomerPropertyIsCorrect()
{
    var fixture = new AutoMoqFixture();

    var expected = fixture.Create<CardHolderCustomer>();
    var builderMock = fixture
        .Freeze<Mock<ICustomerAdapter>>()
        .Setup(x => x.BuildCustomer()).Returns(expected);

    var sut = fixture.Create<CardHolderViewModel>();
    var actual = sut.Customer;

    Assert.Equal(expected, actual);
}
Run Code Online (Sandbox Code Playgroud)

moq mocking autofixture

10
推荐指数
1
解决办法
1805
查看次数

使用自动混合控制对象树的生成深度

我试图用Autofixture控制对象树的生成深度.在某些情况下,我只想生成根对象,在另一组情况下,我可能想要生成一个特定深度的树(2,3,比方说).

class Foo {
    public string Name {get;set;}
    public Bar Bar {get;set;}
    public AnotherType Xpto {get;set;}
    public YetAnotherType Xpto {get;set;}
}

class Bar {
    public string Name {get;set;}
    public string Description {get;set;}
    public AnotherType Xpto {get;set;}
    public YetAnotherType Xpto {get;set;}
    public Xpto Xpto {get;set;}
}

class Xpto {
    public string Description {get;set;}
    public AnotherType Xpto {get;set;}
    public YetAnotherType Xpto {get;set;}
}
Run Code Online (Sandbox Code Playgroud)

通过上面的例子,我希望(深度1)控制生成过程,以便只实例化Foo类,并且不填充该类的Bar属性或任何其他引用类型,或者(深度2)我想要Foo类实例化后,Bar属性使用新的Bar实例填充,但Xpto属性或该类上的任何其他引用类型未填充.

如果我没有在代码库中发现它,Autofixture是否有自定义或行为允许我们进行这种控制?

同样,我想要控制的不是递归,而是对象图的填充深度.

c# autofixture

10
推荐指数
2
解决办法
1901
查看次数

找不到自动夹具循环参考

我正在使用 Autofixture 生成我的测试模型,但在一个实例中,它说我的模型有一个我找不到的循环引用。失败的模型是类RepresentationExpense,我唯一​​能想到的是它与继承相关,因为该类Expense没有相同的问题:

public class RepresentationExpense : Expense
{
    public string GuestName { get; private set; }
    public string GuestCompany { get; private set; }

    public RepresentationExpense(ExpenseId id, ExpenseReportId reportId, EmployeeId employeeId, string description, Payment payment, DateTime created, PaymentMethod paymentMethod, ReceiptId receiptId, string guestName, string guestCompany, string comment = null)
        : base(id, reportId, employeeId, description, payment, created, paymentMethod, CategoryType.Representation, receiptId, comment)
    {
        Verify.ArgumentNotNull(guestName, "guestName");
        Verify.ArgumentNotNull(guestCompany, "guestCompany");

        GuestName = guestName;
        GuestCompany = guestCompany;
    }
}

public class …
Run Code Online (Sandbox Code Playgroud)

c# autofixture

10
推荐指数
2
解决办法
1万
查看次数

使用AutoFixture中的CreateMany省略特定字段

我想创建foo的"很多"实例:

var fixture = new Fixture();
var expectedFoos = fixture.CreateMany<Foo>();
Run Code Online (Sandbox Code Playgroud)

问题是,Foo是一个实体框架实体,具有我不想创建的关系.如果我只需要一个实例,我可以这样做:

var fixture = new Fixture();
var expectedFoo = fixture.Build<Foo>()
                         .Without(foo => foo.Relation1);
                         .Without(foo => foo.Relation2);
Run Code Online (Sandbox Code Playgroud)

但是,如何轻松创建满足此条件的多个实例?我读过有关标本制造商的文章,但这看起来真的有些过分.

我正在寻找一些简单的东西(因为BuildMany不存在而不能编译):

var fixture = new Fixture();
var expectedFoos = fixture.BuildMany<Foo>()
                          .Without(foo => foo.Relation1);
                          .Without(foo => foo.Relation2);
Run Code Online (Sandbox Code Playgroud)

c# unit-testing autofixture

10
推荐指数
2
解决办法
2035
查看次数

AutoFixture和私有属性

是否可以指示AutoFixture还填充私有属性,并使用特定属性(如Ninject.Inject所有类)进行注释?该来源似乎只扫描公共财产:1.这个问题提供了一个特定MyClass的私有设置器的解决方案,但不是私有财产或所有类:2.

我正在使用Moq来模拟服务,最后我想用这些模拟来填充属性.如果我将MyService依赖项公开为,则以下设置可以正常工作public.

一些示例代码:

public class MyController {
    [Inject]
    private IMyService MyService { get; set; }

    public void AMethodUsingMyService() {
        MyService.DoSomething();
        // ...
    }

    // ...
}

public class MyService : IMyService {
    public void DoSomething()
    {
        // ...
    }

    // ...
}

public class MyControllerTest {
    [Theory]
    [AutoMoqData]
    public void MyTest(MyController controller) {
        controller.AMethodUsingMyService();
    }
}
Run Code Online (Sandbox Code Playgroud)

c# autofixture

10
推荐指数
1
解决办法
1837
查看次数

使用AutoFixture 3生成的整数是唯一的吗?

生成的整数是IFixture.Create<int>()唯一的吗?

维基说这些数字是随机的,但它也告诉我们这一点

第一个数字是在[1,255]范围内生成的,因为这是一组对所有数值数据类型有效的值..NET中最小的数字数据类型是System.Byte,它适合此范围.

当使用前255个整数时,随后从范围[256,32767]中选择数字,这对应于System.Int16可用的剩余正数.

GitHub上的两件相关事情:

https://github.com/AutoFixture/AutoFixture/issues/2

https://github.com/AutoFixture/AutoFixture/pull/7

那些单元测试怎么样?

https://github.com/AutoFixture/AutoFixture/blob/master/Src/AutoFixtureUnitTest/GeneratorTest.cs#L33

[Theory, ClassData(typeof(CountTestCases))]
public void StronglyTypedEnumerationYieldsUniqueValues(int count)
{
    // Fixture setup
    var sut = new Generator<T>(new Fixture());
    // Exercise system
    var actual = sut.Take(count);
    // Verify outcome
    Assert.Equal(count, actual.Distinct().Count());
    // Teardown
}
Run Code Online (Sandbox Code Playgroud)

https://github.com/AutoFixture/AutoFixture/blob/master/Src/AutoFixtureUnitTest/GeneratorTest.cs#L57

[Theory, ClassData(typeof(CountTestCases))]
public void WeaklyTypedEnumerationYieldsUniqueValues(int count)
{
    // Fixture setup
    IEnumerable sut = new Generator<T>(new Fixture());
    // Exercise system
    var actual = sut.OfType<T>().Take(count);
    // Verify outcome
    Assert.Equal(count, actual.Distinct().Count());
    // Teardown
}
Run Code Online (Sandbox Code Playgroud)

我还没有找到一个声明,说明生成的数字是唯一的,只有那些可能暗示它的信息,但我可能错了.

c# autofixture

10
推荐指数
2
解决办法
1175
查看次数

在XUnit测试中使用AutoData和MemberData属性

我正面临一个有趣的问题.我发现AutoDataAttribute可用于最小化测试的"排列"部分(通过ctor传递的依赖关系).真棒!

例:

public class AutoMoqDataAttribute : AutoDataAttribute
{
    public AutoMoqDataAttribute()
        : base(new Fixture().Customize(new AutoMoqCustomization()))
    { }
}

[Theory, AutoMoqData]
public void Process_ValidContext_CallsK2Workflows(
    [Frozen]Mock<IK2Datasource> k2,
    [Frozen]Mock<IAppConfiguration> config,
    PrBatchApproveBroker sut)
{
   (...)
}
Run Code Online (Sandbox Code Playgroud)

现在我想使用这个伟大的功能,并将自己的数据注入到这个理论中:

[Theory, AutoMoqData, MemberData("Data")]
public void ExtractPayments_EmptyInvoiceNumber_IgnoresRecordsWithEmptyInvoiceNumber(
        [Frozen]Mock<IExcelDatasource> xls,
        SunSystemExcelDatasource sut,
        List<Row> rows,
        int expectedCount)
{
    (...)
}
Run Code Online (Sandbox Code Playgroud)

问题:AutoData属性将为我生成随机数据.我发现的唯一方法是摆脱AutoData属性并使用MemberData.如果我这样做,我需要自己处理对象实例化:))...

有没有办法同时传递我的类一些"硬编码"数据?

谢谢你,Seb

unit-testing xunit autofixture

10
推荐指数
2
解决办法
2468
查看次数

标签 统计

autofixture ×10

c# ×8

unit-testing ×4

moq ×2

mocking ×1

nunit ×1

readonly-attribute ×1

xunit ×1