Machine.Fakes Property Injection

188 views
Skip to first unread message

jonathan matheus

unread,
Oct 12, 2012, 5:12:37 PM10/12/12
to machin...@googlegroups.com
Is there a way to configure property injection from machine.fakes, specifically using behavior configurations? I want to be able to simplify my specs by removing setting dependencies explicitly for properties.

Jonathan Matheus

unread,
Oct 16, 2012, 8:36:22 PM10/16/12
to machin...@googlegroups.com
Simon,
Thanks for your suggestion, I'll try it out. There are some places where I have to use properties. However, I've also been using property injection more and more, especially in mvc controllers and NServiceBus handlers, where I'm always using a RavenSession or an IBus. It saves on all those ctors that have those same 2 dependencies.

Jonathan

On Mon, Oct 15, 2012 at 4:27 PM, Simon Hohenadl <si...@hohenadl.de> wrote:
Machine.Fakes is geared towards constructor injection. Do you need property injection for a specific reason?

Have you tried something like the following?
It is not really clean to use the Subject in the setup, but I see no reason why this shouldn't work.
Using constructor injection this code would be more straightforward and safer, however

    public class ClassUnderTest
    {
        public IDependency Dependency { getset; }
 
        public void DoIt()
        {
            Dependency.DoItBetter();
        }
    }
 
    public interface IDependency
    {
        void DoItBetter();
    }
 
    [Subject(typeof(ClassUnderTest))]
    public class When_doing_it : WithSubject<ClassUnderTest>
    {
        Establish context = () => With(new YourBehavior(Subject));
 
        Because of = () => Subject.DoIt();
 
        It should_call_the_dependency = () => The<IDependency>().WasToldTo(x => x.DoItBetter());
    }
 
    internal class YourBehavior
    {
        static ClassUnderTest _subject;
 
        public YourBehavior(ClassUnderTest subject)
        {
            _subject = subject;
        }
 
        OnEstablish context = accessor => _subject.Dependency = accessor.The<IDependency>();
    }

--
You received this message because you are subscribed to the Google Groups "machine_users" group.
To view this discussion on the web visit https://groups.google.com/d/msg/machine_users/-/64zyySJAXKoJ.

To post to this group, send email to machin...@googlegroups.com.
To unsubscribe from this group, send email to machine_user...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/machine_users?hl=en.

Jeremy Wilkins

unread,
Dec 16, 2013, 6:10:01 PM12/16/13
to machin...@googlegroups.com
I don't generally recommend doing property injection since that creates strange dependency chains that the users of your class may not be aware of.  This is why constructor injection is usually preferred.
However, there a few rare cases when this is necessary.

Chris, you can manually set the value and this is fine if you only have one instance where you need to set the property, but as soon as you have to do this again you should use Simon's recommended method.
That way, when you need to add another injected property to the setup (also not recommended), you will only have one place to fix it for all of your tests.
This follows the DRY principle.  However, jumping to Simon's solution right off is not recommended either, that smells of needless complexity if you only ever do it once.

On Monday, February 25, 2013 1:22:21 PM UTC-6, Simon Hohenadl wrote:
Yes, that would be the way to do it without behavior configuration.
Reply all
Reply to author
Forward
0 new messages