Mark Thanks for the information, it works a treat. Dave
On Monday, 10 August 2015, 1:12, Mark Payne <marka...@hotmail.com> wrote: David, Yes, you'll also need to set the controller service in your processor. Sorry, I forgot to mention that. So after the call to runner.enableControllerService(), and before the call to runner.run(), you would do: runner.setProperty(CacheTester.CACHE_SERVICE, "my-cache"); This way, the CacheTester processor knows to reference that controller service. So your method will look like: @Test public void checkCache() throws InitializationException, IOException{ final TestRunner runner = TestRunners.newTestRunner(CacheTester.class); final StandardCacheService cacheService = new StandardCacheService(); runner.addControllerService("my-cache", cacheService); runner.setProperty(cacheService, StandardCacheService.DATAFILE, "/data/TEST_FILE"); runner.setProperty(CacheTester.CACHE_SERVICE, "my-cache"); runner.enableControllerService(cacheService); runner.run(); } Thanks -Mark ---------------------------------------- > Date: Sun, 9 Aug 2015 21:06:18 +0000 > From: davidrsm...@btinternet.com > To: dev@nifi.apache.org > Subject: Re: Instantiating a Controller Service in a Junit test > > Mark > Thanks for the reply, I have changed my test as you suggested, see below: > @Test > public void checkCache() throws InitializationException, IOException{ > final TestRunner runner = TestRunners.newTestRunner(CacheTester.class); > final StandardCacheService cacheService = new StandardCacheService(); > runner.addControllerService("my-cache", cacheService); > runner.setProperty(cacheService, StandardCacheService.DATAFILE, > "/data/TEST_FILE"); > runner.enableControllerService(cacheService); > runner.run(); > } > > > When I run my test I now get a null pointer exception in my CacheTester > class. It appears the cache in my CacheTester class doesn't exist, when I > comment out all the calls to the cache methods the test passes. > If I understand the code above correctly I don't believe I have set the > PropertyDescriptor in my CacheTester processor class which is shown below has > been set, am I correct?: > public static final PropertyDescriptor CACHE_SERVICE = new > PropertyDescriptor.Builder() .name("Cache Service") .description("The > Controller Service to use in order to obtain a Cache Service") > .required(false) .identifiesControllerService(CacheServiceAPI.class) .build(); > > > BTW, the former I mentioned in my original post was referring to the > descriptions I had given about how to instantiate the Controller Service. > Many thanksDave > > > On Sunday, 9 August 2015, 21:05, Mark Payne <marka...@hotmail.com> wrote: > > > Hi David, > > You should be able to just import your StandardCacheService in your unit test. > > You can then instantiate the controller service and use > TestRunner.addControllerService, as you're doing here. > At that point, to set the properties, you can use TestRunner.setProperty. For > example: > > final StandardCacheService cacheService = new StandardCacheService(); > runner.addControllerService("my-cache", cacheService); > runner.setProperty(cacheService, StandardCacheService.DATAFILE, "/data/file"); > runner.enableControllerService(cacheService); > > There is no need to actually create the Logger and call initialize, as that > is handled for you when you call TestRunner.addControllerService. > > In your message, can you explain a bit further what you meant by > "If the former is correct how do I set the PropertyDescriptor as when I did > try this option the StandardCacheService.DATAFILE PropertyDescriptor was > never visible?" > > It's important that you not mark the PropertyDescriptor as private, or else > you won't be able to access it, and you'll also want to ensure that > it is returned by your getSupportedPropertyDescriptors() method. If I am > misunderstanding the comment, please advise. > > Let me know if this clears things up for you, or if you need any more details. > > If anything doesn't make sense, just give a shout - we're always happy to > help! :) > > Thanks > -Mark > > > ---------------------------------------- >> Date: Sun, 9 Aug 2015 14:40:53 +0000 >> From: davidrsm...@btinternet.com >> To: dev@nifi.apache.org >> Subject: Instantiating a Controller Service in a Junit test >> >> Hi >> I have written a simple Cache Controller Service, this Controller Service >> has a property which if populated allows the cache to be populated when it >> is intialized. I have also written a simple processor that allows me to >> utilize the Controller Service and checks some of the preloaded values and >> also checks some of the cache methods. >> I now want to write some Junit tests for my processor, and I want to >> instantiate my Cache Controller Service. I have looked at other Junit test >> classes in the nifi-0.2.1 source release for some guidance on how to do >> this, looking particularly at the test classes for the DetectDuplicate >> processor. >> I have imported the Controller Service API and based on what I saw in the >> DetectDuplicate tests I have created a test shown below: >> public class TestCacheTester { >> >> @Test >> public void checkCache() throws InitializationException, IOException { >> >> final TestRunner runner = TestRunners.newTestRunner(CacheTester.class); >> final StandardCacheService testCache = createService(); >> >> runner.addControllerService("my-cache", testCache ); >> runner.enableControllerService(testCache); >> runner.setProperty("Cache Service", "my-cache"); >> runner.enqueue(Paths.get("src/test/resources/hello.txt")); >> runner.run(); >> } >> >> private StandardCacheService createService() throws InitializationException { >> >> final StandardCacheService cacheService = new StandardCacheService(); >> final ComponentLog logger = new MockProcessorLog("cacheService", >> cacheService); >> final MockControllerServiceInitializationContext clientInitContext = new >> MockControllerServiceInitializationContext(cacheService, "cacheService", >> logger); >> cacheService.initialize(clientInitContext); >> >> return cacheService; >> } >> >> static final class StandardCacheService extends AbstractControllerService >> implements CacheServiceAPI { >> >> public static Map<String, String> cacheMap = new HashMap<String, String>(); >> >> @Override >> public void onPropertyModified(final PropertyDescriptor descriptor, final >> String oldValue, final String newValue) { >> } >> >> @Override >> protected java.util.List<PropertyDescriptor> >> getSupportedPropertyDescriptors() { >> final List<PropertyDescriptor> props = new ArrayList<>(); >> //props.add(StandardCacheService.DATAFILE); >> return props; >> } >> >> @OnEnabled >> public void onConfigured(final ConfigurationContext context) throws >> InitializationException { >> // configContext = context; >> initializeCache("/data/TEST_FILE"); >> } >> >> private void initializeCache(String fileName) { >> try { >> BufferedReader br = new BufferedReader(new FileReader(fileName)); >> String line = ""; >> while((line = br.readLine()) != null){ >> String [] values = line.split(","); >> cacheMap.put(values[0], values[1]); >> } >> br.close(); >> } catch (IOException e) { >> System.out.println("IO Exception " + e); >> } >> } >> >> ........ Plus other Cache Methods snipped for brevity................ >> >> My question is should I actually be importing my StandardCacheService class >> and setting its property descriptor or is the above listing where I have >> effectively rewritten StandardCacheService class in the Junit Test Class the >> correct way of using a Controller Service in a Junit test? >> If the former is correct how do I set the PropertyDescriptor as when I did >> try this option the StandardCacheService.DATAFILE PropertyDescriptor was >> never visible? >> Many thanksDave >> >> > > >