{"metadata":{"image":[],"title":"","description":""},"api":{"url":"","auth":"required","params":[],"results":{"codes":[]},"settings":""},"next":{"description":"","pages":[]},"title":"Using a behavior to define state","type":"basic","slug":"using-a-behavior-to-define-state","excerpt":"","body":"Let's pretend that we want some dummy data available for use in our specs. We can ensure that each spec gets its own data set by creating a behavior. \n\nFirst, let's register our behavior. This time, we want it to only apply to specs that implement a specific interface: INeedDummyData.\n[block:code]\n{\n \"codes\": [\n {\n \"code\": \"WhenTesting<INeedDummyData>().EnrichWith<DummyDataProviderBehavior>();\",\n \"language\": \"csharp\"\n }\n ]\n}\n[/block]\nNow let's define our INeedDummyData interface:\n[block:code]\n{\n \"codes\": [\n {\n \"code\": \" public interface INeedDummyData : ISpecs\\n {\\n IEnumerable<Foo> Foos { get; set; }\\n }\",\n \"language\": \"csharp\"\n }\n ]\n}\n[/block]\nThe interface defines a single writable property: Foos. Our behavior will create some Foo objects and assign them there for the spec to use. \n\nHere's our behavior: \n[block:code]\n{\n \"codes\": [\n {\n \"code\": \" public class DummyDataProviderBehavior : Behavior<INeedDummyData>\\n {\\n public override void Given(INeedDummyData instance)\\n {\\n instance.Foos = new[]\\n {\\n new Foo {Id = Guid.NewGuid(), Name = \\\"Foo 1\\\"},\\n new Foo {Id = Guid.NewGuid(), Name = \\\"Foo 2\\\"},\\n new Foo {Id = Guid.NewGuid(), Name = \\\"Foo 3\\\"},\\n new Foo {Id = Guid.NewGuid(), Name = \\\"Foo 4\\\"},\\n new Foo {Id = Guid.NewGuid(), Name = \\\"Foo 5\\\"},\\n };\\n }\\n }\",\n \"language\": \"text\"\n }\n ]\n}\n[/block]\nNow our specs have access to a collection of Foo's that they can use, without having to do anything special:\n[block:code]\n{\n \"codes\": [\n {\n \"code\": \" public class when_a_spec_has_the_right_marker_interface \\n : SpecsFor<Foo>, INeedDummyData\\n {\\n public IEnumerable<Foo> Foos { get; set; }\\n\\n [Test]\\n public void then_it_injects_some_foos()\\n {\\n Foos.ShouldNotBeEmpty();\\n }\\n }\",\n \"language\": \"csharp\"\n }\n ]\n}\n[/block]\nYou can also use a behavior to modify the [auto-mocking](doc:about-auto-mocking) container: \n[block:code]\n{\n \"codes\": [\n {\n \"code\": \"//In your spec config..\\nWhenTesting<INeedMockHelloService>().EnrichWith<MockHelloServiceBehavior>();\\nWhenTesting<INeedRealHelloService>().EnrichWith<RealHelloServiceBehavior>();\\n\\n//These would go somewhere else\\npublic class MockHelloServiceBehavior : Behavior<INeedMockHelloService>\\n{\\n public override void SpecInit(INeedMockHelloService instance)\\n {\\n instance.GetMockFor<IHelloService>()\\n .Setup(x => x.SayHello())\\n .Returns(\\\"Hello from Moq instance!\\\");\\n }\\n}\\n\\npublic class RealHelloServiceBehavior : Behavior<INeedRealHelloService>\\n{\\n public override void SpecInit(INeedRealHelloService instance)\\n {\\n instance.MockContainer.Inject<IHelloService>(new HelloService());\\n }\\n}\",\n \"language\": \"csharp\"\n }\n ]\n}\n[/block]\nSpecs can then request either the real service or the pre-configured mock object by implementing the corresponding marker interface. \n[block:code]\n{\n \"codes\": [\n {\n \"code\": \" public class HelloSpecs\\n {\\n public class when_using_the_real_hello_service \\n : SpecsFor<HelloConsumer>, INeedRealHelloService\\n {\\n [Test]\\n public void then_it_returns_the_real_string()\\n {\\n SUT.GetHelloMessage().ShouldEqual(\\\"Hello from HelloService!\\\");\\n }\\n }\\n\\n public class when_using_the_mock_hello_service \\n : SpecsFor<HelloConsumer>, INeedMockHelloService\\n {\\n [Test]\\n public void then_it_returns_the_mock_string()\\n {\\n SUT.GetHelloMessage().ShouldEqual(\\\"Hello from Moq instance!\\\");\\n }\\n }\\n }\",\n \"language\": \"csharp\"\n }\n ]\n}\n[/block]\nBehaviors can do more than just define state before a spec executes. [They can also clean things up after a spec executes](doc:wrapping-a-spec-with-a-behavior).","updates":[],"order":4,"isReference":false,"hidden":false,"sync_unique":"","link_url":"","link_external":false,"_id":"56b1401d4b05c50d001ceb3b","project":"54471fc9e12a270800028adc","category":{"sync":{"isSync":false,"url":""},"pages":["5447ef8d0319802200fc0713","56ac1ec3aa91300d00bede9b","56ac213d0bbe170d00f11272","56ac21d2c69a430d008aabb3","56b1401d4b05c50d001ceb3b","56c72ca5862f940d0056475d","56c75ec053cafe0d00a53d7b"],"title":"Convention System","slug":"convention-system","order":6,"from_sync":false,"reference":false,"_id":"5447ed230319802200fc0702","__v":7,"version":"54471fc9e12a270800028adf","createdAt":"2014-10-22T17:45:07.793Z","project":"54471fc9e12a270800028adc"},"createdAt":"2016-02-02T23:47:41.827Z","githubsync":"","version":{"version":"1.0","version_clean":"1.0.0","codename":"","is_stable":true,"is_beta":false,"is_hidden":false,"is_deprecated":false,"categories":["54471fc9e12a270800028ae0","5447b9e7b96a63140077d747","5447be130319802200fc0620","5447ed118d7af31a00dd411c","5447ed230319802200fc0702","5448524c4544c30800241f41","544854504544c30800241f4d","544854af4544c30800241f50","544854e74544c30800241f51","54485557c1b42e08005b82bf"],"_id":"54471fc9e12a270800028adf","__v":10,"project":"54471fc9e12a270800028adc","releaseDate":"2014-10-22T03:08:57.750Z","createdAt":"2014-10-22T03:08:57.750Z"},"user":"54471f91beb6320800da6f75","__v":9}