{"__v":9,"_id":"553dec6a1a946a0d00ad6f2d","category":{"__v":3,"_id":"553dec691a946a0d00ad6f2b","pages":["553dec6a1a946a0d00ad6f2d","5543575b62b30e0d004b16f9","5561ed6c4bfe45170030a059"],"project":"553dec691a946a0d00ad6f27","version":"553dec691a946a0d00ad6f2a","sync":{"url":"","isSync":false},"reference":false,"createdAt":"2015-04-27T07:59:37.956Z","from_sync":false,"order":0,"slug":"getting-started","title":"Getting Started"},"project":"553dec691a946a0d00ad6f27","user":"54c4b05742190d0d00f5fbde","version":{"__v":2,"_id":"553dec691a946a0d00ad6f2a","project":"553dec691a946a0d00ad6f27","createdAt":"2015-04-27T07:59:37.477Z","releaseDate":"2015-04-27T07:59:37.477Z","categories":["553dec691a946a0d00ad6f2b","5543585f795b590d001dc89a"],"is_deprecated":false,"is_hidden":false,"is_beta":false,"is_stable":true,"codename":"","version_clean":"1.0.0","version":"1.0"},"updates":[],"next":{"pages":[],"description":""},"createdAt":"2015-04-27T07:59:38.667Z","link_external":false,"link_url":"","githubsync":"","sync_unique":"","hidden":false,"api":{"results":{"codes":[]},"settings":"","auth":"required","params":[],"url":""},"isReference":false,"order":1,"body":"[block:api-header]\n{\n  \"type\": \"basic\",\n  \"title\": \"Add NuGet package\"\n}\n[/block]\nThe best way to get started with Dossier is to install the package into your test project via NuGet:\n\n> Install-Package TestStack.Dossier\n[block:api-header]\n{\n  \"type\": \"basic\",\n  \"title\": \"Building an object, creating a custom test data builder or generating a value?\"\n}\n[/block]\nAre you:\n\n* [Building a DTO, view model, or other class you don't want to write a custom test data builder class for](doc:create-object-without-requiring-custom-builder-cla)?\n* [Generating a value](doc:anonymous-values-and-equivalence-classes)?\n* Creating a custom test data builder class? Carry on reading...\n[block:api-header]\n{\n  \"type\": \"basic\",\n  \"title\": \"Create a custom test data builder class\"\n}\n[/block]\nIf you want to build a custom builder class, e.g. for a domain object, you can use the builder as documentation and also to make the experience of building that class in your tests more rich.\n\nConsider the following example of a domain object:\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"public class Customer\\n{\\n    protected Customer() {}\\n\\n    public Customer(string firstName, string lastName, int yearJoined)\\n    {\\n        if (string.IsNullOrEmpty(firstName))\\n            throw new ArgumentNullException(\\\"firstName\\\");\\n        if (string.IsNullOrEmpty(lastName))\\n            throw new ArgumentNullException(\\\"lastName\\\");\\n\\n        FirstName = firstName;\\n        LastName = lastName;\\n        YearJoined = yearJoined;\\n    }\\n\\n    public virtual int CustomerForHowManyYears(DateTime since)\\n    {\\n        if (since.Year < YearJoined)\\n            throw new ArgumentException(\\\"Date must be on year or after year that customer joined.\\\", \\\"since\\\");\\n        return since.Year - YearJoined;\\n    }\\n\\n    public virtual string FirstName { get; private set; }\\n    public virtual string LastName { get; private set; }\\n    public virtual int YearJoined { get; private set; }\\n}\",\n      \"language\": \"csharp\"\n    }\n  ]\n}\n[/block]\nIf you decide to create a `CustomerBuilder` custom test data builder class for it then you start by extending Dossier's `TestDataBuilder` class. The first generic parameter is the class that you are writing a builder for (the `Customer` class in this case) and the second generic parameter is the builder class itself (`CustomerBuilder` in this case).\n\nIt might be surprising to have this recursive type definition, but it is needed to facilitate fluent method chaining for the base class methods (e.g. [Set](doc:basic-builder-methods)).\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"public class CustomerBuilder : TestDataBuilder<Customer, CustomerBuilder>\\n{\\n  public CustomerBuilder()\\n  {\\n    // Can set up defaults here - any that you don't set or subsequently override\\n    //   will have an anonymous value generated by default\\n    WhoJoinedIn(2013);\\n  }\\n\\n  // Note: the methods are virtual - this is important if you want to build lists (as per below)\\n  public virtual CustomerBuilder WithFirstName(string firstName)\\n  {\\n    return Set(x => x.FirstName, firstName);\\n  }\\n\\n  // Note: we typically only start with the methods that are strictly needed so the\\n  //   builders are quick to write and aren't bloated\\n  public virtual CustomerBuilder WithLastName(string lastName)\\n  {\\n    return Set(x => x.LastName, lastName);\\n  }\\n\\n  public virtual CustomerBuilder WhoJoinedIn(int yearJoined)\\n  {\\n    return Set(x => x.YearJoined, yearJoined);\\n  }\\n\\n  // This method is optional, by default it uses `BuildUsing<PublicPropertySettersFactory>()`\\n  protected override Customer BuildObject()\\n  {\\n    return BuildUsing<CallConstructorFactory>();\\n    // or, if you need more control / can't use the auto-construction assumptions\\n    return new Customer(\\n      Get(x => x.FirstName),\\n      Get(x => x.LastName),\\n      Get(x => x.YearJoined)\\n    );\\n  }\\n}\",\n      \"language\": \"csharp\"\n    }\n  ]\n}\n[/block]\nNote: that overriding the BuildObject method is [optional](doc:build-objects-without-calling-constructor).\n[block:api-header]\n{\n  \"type\": \"basic\",\n  \"title\": \"Use the builder in a test\"\n}\n[/block]\n\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"var customer = new CustomerBuilder()\\n\\t.WithFirstName(\\\"Robert\\\")\\n  .Build();\",\n      \"language\": \"csharp\"\n    }\n  ]\n}\n[/block]\n\n[block:api-header]\n{\n  \"type\": \"basic\",\n  \"title\": \"Where next?\"\n}\n[/block]\nConsider using the [Object Mother pattern](http://martinfowler.com/bliki/ObjectMother.html) in combination with the builders. See [Rob Moore's blog post](http://robdmoore.id.au/blog/2013/05/26/test-data-generation-the-right-way-object-mother-test-data-builders-nsubstitute-nbuilder/) for a description of the theory behind this approach.\n\nThe usage documentation should get you across the other capabilities of this library. It's probably best to start with [Basic builder methods](doc:basic-builder-methods).","excerpt":"This page will help you get started with Dossier. You'll be up and running in a jiffy!","slug":"getting-started","type":"basic","title":"Getting Started with Dossier"}

Getting Started with Dossier

This page will help you get started with Dossier. You'll be up and running in a jiffy!

[block:api-header] { "type": "basic", "title": "Add NuGet package" } [/block] The best way to get started with Dossier is to install the package into your test project via NuGet: > Install-Package TestStack.Dossier [block:api-header] { "type": "basic", "title": "Building an object, creating a custom test data builder or generating a value?" } [/block] Are you: * [Building a DTO, view model, or other class you don't want to write a custom test data builder class for](doc:create-object-without-requiring-custom-builder-cla)? * [Generating a value](doc:anonymous-values-and-equivalence-classes)? * Creating a custom test data builder class? Carry on reading... [block:api-header] { "type": "basic", "title": "Create a custom test data builder class" } [/block] If you want to build a custom builder class, e.g. for a domain object, you can use the builder as documentation and also to make the experience of building that class in your tests more rich. Consider the following example of a domain object: [block:code] { "codes": [ { "code": "public class Customer\n{\n protected Customer() {}\n\n public Customer(string firstName, string lastName, int yearJoined)\n {\n if (string.IsNullOrEmpty(firstName))\n throw new ArgumentNullException(\"firstName\");\n if (string.IsNullOrEmpty(lastName))\n throw new ArgumentNullException(\"lastName\");\n\n FirstName = firstName;\n LastName = lastName;\n YearJoined = yearJoined;\n }\n\n public virtual int CustomerForHowManyYears(DateTime since)\n {\n if (since.Year < YearJoined)\n throw new ArgumentException(\"Date must be on year or after year that customer joined.\", \"since\");\n return since.Year - YearJoined;\n }\n\n public virtual string FirstName { get; private set; }\n public virtual string LastName { get; private set; }\n public virtual int YearJoined { get; private set; }\n}", "language": "csharp" } ] } [/block] If you decide to create a `CustomerBuilder` custom test data builder class for it then you start by extending Dossier's `TestDataBuilder` class. The first generic parameter is the class that you are writing a builder for (the `Customer` class in this case) and the second generic parameter is the builder class itself (`CustomerBuilder` in this case). It might be surprising to have this recursive type definition, but it is needed to facilitate fluent method chaining for the base class methods (e.g. [Set](doc:basic-builder-methods)). [block:code] { "codes": [ { "code": "public class CustomerBuilder : TestDataBuilder<Customer, CustomerBuilder>\n{\n public CustomerBuilder()\n {\n // Can set up defaults here - any that you don't set or subsequently override\n // will have an anonymous value generated by default\n WhoJoinedIn(2013);\n }\n\n // Note: the methods are virtual - this is important if you want to build lists (as per below)\n public virtual CustomerBuilder WithFirstName(string firstName)\n {\n return Set(x => x.FirstName, firstName);\n }\n\n // Note: we typically only start with the methods that are strictly needed so the\n // builders are quick to write and aren't bloated\n public virtual CustomerBuilder WithLastName(string lastName)\n {\n return Set(x => x.LastName, lastName);\n }\n\n public virtual CustomerBuilder WhoJoinedIn(int yearJoined)\n {\n return Set(x => x.YearJoined, yearJoined);\n }\n\n // This method is optional, by default it uses `BuildUsing<PublicPropertySettersFactory>()`\n protected override Customer BuildObject()\n {\n return BuildUsing<CallConstructorFactory>();\n // or, if you need more control / can't use the auto-construction assumptions\n return new Customer(\n Get(x => x.FirstName),\n Get(x => x.LastName),\n Get(x => x.YearJoined)\n );\n }\n}", "language": "csharp" } ] } [/block] Note: that overriding the BuildObject method is [optional](doc:build-objects-without-calling-constructor). [block:api-header] { "type": "basic", "title": "Use the builder in a test" } [/block] [block:code] { "codes": [ { "code": "var customer = new CustomerBuilder()\n\t.WithFirstName(\"Robert\")\n .Build();", "language": "csharp" } ] } [/block] [block:api-header] { "type": "basic", "title": "Where next?" } [/block] Consider using the [Object Mother pattern](http://martinfowler.com/bliki/ObjectMother.html) in combination with the builders. See [Rob Moore's blog post](http://robdmoore.id.au/blog/2013/05/26/test-data-generation-the-right-way-object-mother-test-data-builders-nsubstitute-nbuilder/) for a description of the theory behind this approach. The usage documentation should get you across the other capabilities of this library. It's probably best to start with [Basic builder methods](doc:basic-builder-methods).