Fixture.Customize 与 Fixture.Register

coc*_*lla 5 autofixture

Customize请解释和之间的功能差异Register,以及何时使用其中之一。下面的示例TestCustomize失败并TestRegister通过。我希望自定义脚本能够正常工作。它的英文读起来是:“生成 时HttpClient,在提供样本之前对其使用后处理 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());
}
Run Code Online (Sandbox Code Playgroud)

Mar*_*ann 3

Customize这与vs无关Register。事实上,如果您查看 的源代码Register,您会发现它只是 的一种便捷方法Customize

问题出在使用上Do。如果您查看 的签名Do,您会发现它具有以下类型:

IPostprocessComposer<T> Do(Action<T> action)
Run Code Online (Sandbox Code Playgroud)

请注意,该方法返回一个值。在函数式风格中,或者,如果您愿意的话,在命令-查询分离之后,该方法不会改变定义它的实例,而是返回一个具有更改后的行为的新对象。

当一个人写道:

c.Do(x => x.BaseAddress = new Uri("http://myval"));
Run Code Online (Sandbox Code Playgroud)

我们会立即丢弃行为改变后的返回值。在 F# 或 Haskell 等语言中,如果您编写这样的代码,您会收到编译时通知,告诉您将忽略函数调用的返回值,但 C# 不会这样做。

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

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

您仍然需要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());
}
Run Code Online (Sandbox Code Playgroud)