+architecture This initially began as an internal APIM discussion for avoiding hard coded dependencies within the code we are writing for C5 to make them more unit testable(Being able to do dependency injection[1]). But as suggested by Akila I think this is a good thing to talk about publicly as all products can benefit.
Akila suggested using something like Google Juice[2] for this purpose. Im +1 for using this. Would like to here your thoughts on this. [1] https://www.youtube.com/watch?v=IKD2-MAkXyQ [2] https://github.com/google/guice On 31 October 2016 at 13:06, Uvindra Dias Jayasinha <[email protected]> wrote: > > Hi Sajith, > > On 31 October 2016 at 12:34, Sajith Kariyawasam <[email protected]> wrote: > >> Hi Uvindra, >> >> On Mon, Oct 31, 2016 at 10:37 AM, Uvindra Dias Jayasinha < >> [email protected]> wrote: >> >>> Hi All, >>> >>> Im addressing the DOA interface usage for C5 in this mail but this >>> applies to all new code we write in C5 so its a good thing for us all to >>> note down. >>> >>> Those of you working on the APIConsumerImpl and APIProviderImpl for C5 >>> were asking what is the preferable way to use the DAO interface in that >>> code. At the time I said you can use it however you want to, but thinking >>> about this I think we should all conform to the following usage. >>> >>> You should not have any hard coded dependency to the the DOA interface >>> within the code of APIConsumerImpl and APIProviderImpl. That means doing, >>> >>> ApiDAO apiDAO = DAOFactory.getApiDAO(); >>> >>> inside the Consumer or Provider classes is a *no no*. >>> >>> Ok now let me explain why, >>> >>> *The problem* >>> If an external dependency is hard coded inside a given class you cannot >>> unit test that class without having that external dependency present. So in >>> this case the external dependency is the DAO which is an interface to the >>> database. If its hard coded in the Consumer or Provider classes we cannot >>> unit test the Consumer/Provider classes without configuring a real >>> database. Heavy weight resources such as databases or file systems make >>> unit testing difficult to do and discourage it. >>> >>> >> can't we just *mock(DAOFactory.class)* ? >> > > We can mock it provided we haven't already constructed an instance in our > code. But calling DAOFactory.getApiDAO() in our code means we have already > committed to the implementation provided by the factory and cannot use a > mocked implementation. > > >> At some point of time of the code, we *have* to invoke >> DAOFactory.getApiDAO() methods to do the object creation, meaning the class >> we write that code is not unit testable ? >> > > Yes, that code will not be unit testable. The goal is to reduce the amount > of non unit testable code as much as possible. > > >> >> Shouldn't this solution introduce a fat constructor? >> > > It does but the advantage we get from doing things this way far outweighs > the constructor being fat. The consumer and Provider classes will only be > constructed in one place I believe so that will not be an issue. We can > also provide a helper method that calls that fat constructor internally to > make it easier for the caller. > > >> *The solution* >>> Pass an instance of the interface to the heavy weight resource as a >>> constructor parameter to the class that needs to use it. So in this case it >>> should be, >>> >>> public APIConsumerImpl(ApiDAO apiDAO, ApplicationDAO appDAO, >>> APISubscriptionDAO apiSubscriptionDAO) { >>> this.apiDAO = apiDAO; >>> this.appDAO = appDAO; >>> this.apiSubscriptionDAO = apiSubscriptionDAO; >>> } >>> >>> Passing it this way means we can now provide a mock implementation of >>> the DOA interfaces when constructing the Consumer and Provider classes >>> using a library such as mockito[1] and easily write unit tests. >>> >>> The reason why we had to rely on integration tests heavily earlier even >>> to do the simplest form of testing was because we did not follow this >>> practice of not having hard coded dependencies. Please keep this principle >>> in mind when designing your classes for C5 or our testing strategy will not >>> work. >>> >>> I'm sure some of you will have questions, so please ask. >>> >>> [1] http://site.mockito.org/ >>> >>> -- >>> Regards, >>> Uvindra >>> >>> Mobile: 777733962 >>> >> >> >> >> -- >> Sajith Kariyawasam >> *Associate Tech Lead* >> *WSO2 Inc.; http://wso2.com <http://wso2.com/>* >> *Committer and PMC member, Apache Stratos * >> *AMIE (SL)* >> *Mobile: 0772269575* >> > > > > -- > Regards, > Uvindra > > Mobile: 777733962 > -- Regards, Uvindra Mobile: 777733962
_______________________________________________ Architecture mailing list [email protected] https://mail.wso2.org/cgi-bin/mailman/listinfo/architecture
