Fixture.Customize vs Fixture.Register

问题描述 投票:1回答:1

请解释自定义和注册之间的功能差异,何时使用另一个。下面的TestCustomize示例失败,TestRegister通过。我希望自定义脚本能正常工作。它用英语读给我:“在生成HttpClient时,在提供specimin之前使用后处理lambda”。

但我得到的是一个带有guid的http地址,显然是由AutoFixture生成的。

[Fact]
public void TestCustomize()
{
    var fixture = new Fixture();
    fixture.Customize<HttpClient>(c =>
    {
        //c.OmitAutoProperties(); makes no difference
        c.Do(x => x.BaseAddress = new Uri("http://myval"));
        return c;
    });
    var client = fixture.Create<HttpClient>();
    Assert.Equal("http://myval/", client.BaseAddress.ToString());
}

[Fact]
public void TestRegister()
{
    var fixture = new Fixture();
    fixture.Register(() => new HttpClient
    {
        BaseAddress = new Uri("http://myval")
    });
    var client = fixture.Create<HttpClient>();
    Assert.Equal("http://myval/", client.BaseAddress.ToString());
}
autofixture
1个回答
1
投票

这与CustomizeRegister无关。事实上,如果你看看source code for Register,你会发现它只是一种比Customize更方便的方法。

问题在于使用Do。如果你看看Do的签名,你会发现它有这种类型:

IPostprocessComposer<T> Do(Action<T> action)

请注意,该方法返回一个值。在功能样式中,或者,如果您愿意,在Command-Query Separation之后,该方法不会改变定义它的实例,而是返回具有已更改行为的新对象。

当一个人写道:

c.Do(x => x.BaseAddress = new Uri("http://myval"));

一个用改变的行为立即丢弃返回值。在像F#或Haskell这样的语言中,如果编写这样的代码,就会得到一个编译时通知,告诉你要忽略函数调用的返回值,但C#不会这样做。

无论如何,AutoFixture的API被设计为fluent interfaces。目的是将方法调用链接在一起:

fixture.Customize<HttpClient>(c => c
    .Without(x => x.BaseAddress)
    .Do(x => x.BaseAddress = new Uri("http://myval")));

你仍然需要Without(或者,如果你愿意,OmitAutoProperties)来关闭默认的自动属性行为,否则,BaseAddress将被自动属性功能覆盖。

此版本的测试通过:

[Fact]
public void TestCustomize()
{
    var fixture = new Fixture();
    fixture.Customize<HttpClient>(c => c
        .Without(x => x.BaseAddress)
        .Do(x => x.BaseAddress = new Uri("http://myval")));

    var client = fixture.Create<HttpClient>();

    Assert.Equal("http://myval/", client.BaseAddress.ToString());
}
© www.soinside.com 2019 - 2024. All rights reserved.