简体   繁体   中英

How best to Refactor code that is composed of other private objects that are created in the Constructor

I have the following code that was written without Tests but is actually quite well designed and loosly coupled. The CachedBindingListView constructs a number of objects namely the page provider and the Cache. As Follows.

    /// <summary>
    /// Inner data cache
    /// </summary>
    private Cache<T> InnerCache { get; set; }

    /// <summary>
    /// Page provider
    /// </summary>
    private PageProvider<T> PageProvider { get; set; }

    /// <summary>
    /// the Request object that is built with a filter, sort, no of pages etc.
    /// </summary>
    private BindingListRequest<T> BindingListRequest { get; set; }

    #endregion

    #region Constructor

    /// <summary>
    /// New object
    /// </summary>
    /// <param name="bindingListRequest">Request for a particular set of Business Objects</param>
    public CachedBindingListView(BindingListRequest<T> bindingListRequest)
    {
        BindingListRequest = bindingListRequest;
        PageProvider = new PageProvider<T>(BindingListRequest);
        InnerCache = new Cache<T>(PageProvider);
    }

I have written tests for the BindingListRequest, PageProvider and InnerCache. but now want to start writing Tests for the CachedBindingList. The constructor currently takes a BindingListRequest and constructs a page provider and inner cache based on this.

For test purposes I want to be able to provide at TestDouble for PageProvider and Cache.

What are the best ways of doing this. I have considered the following options.

1) Add the PageProvider and InnerCache to the Constructor and inject the appropriate type in when required.

2) Use A DI framework to Resolve the PageProvider and Cache within the CachedBindingListView constructor. This would involve either injecting the DI container into the CachedBindingListView constructor or making it global.

3) Creating a factory that creates PageProvider and Cache and possibly even the CachedBindingListView and using this factory to create the PageProvider and InnerCache in the CachedBingingListView's constructor. This would again involve either making the factory global or injecting it into the CachedBingingListView's Constructor.

4) Making the PageProvider and InnerCache Properties Public and use a DI framework to create the CachedBindingListView and inject the PageProvider and InnerCache properties via property injection. Thus allowing me to override the Cache and PageProvider being injected during testing.

I can see how any of these can work but all of them seem a bit unwieldly and forced. What are the opinions out there. What advice does anyone have on the best way of doing this.

thanks GD

If you just want to be able to test it - one option is to make a protected constructor with all three properties injected. Then in your test make a FakeCachedBindingListView that inherits from the CachedBindingListView and inject the needed stubs, mocks (pick your poison).

That's the one I'd go with, anyway.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM