Page 1 of 2 12 LastLast
Results 1 to 10 of 13

Thread: Injecting messages for validation testing

  1. #1
    Join Date
    Nov 2008
    Posts
    742

    Default Injecting messages for validation testing

    Hopefully there's a quick and easy answer for this one.

    I'm starting unit testing on my project. The class in question is essentially a form with some fields and the following validate method:

    Code:
    public boolean validate(MessageContext context)
    Inside the message, I'm using MessageBuilders to construct the message, using a code to generate the message text referencing the resource bundle for the flow.

    For the purposes of testing, I'm setting various properties of the form, then calling validate() passing in a DefaultMessageContext. However, not surprisingly, the codes I'm passing to my MessageBuilder aren't being evaluated since it isn't referencing my properties file.

    I can't seem to figure out where to configure this so my properties file gets read so my messages resolve correctly. Can someone point me in the right direction?


    As a side question, I'm looking for a way to universally get at my resources. During development, I typically run my test classes directly. But our test classes are also a part of our ant build process. The working directories when executing each are different, so I can't be sure of where I am in the directory structure so it's difficult to figure out how to get to the web/WEB-INF/flows/... etc. This seems like a common problem, so I'm hoping there's a common solution to this one as well.

  2. #2
    Join Date
    Nov 2008
    Posts
    742

    Default

    This should be a common case, right? Load a flow for a test, load a resource bundle, start the test.

    All I need is the recommended way to load a resource bundle.

    Anyone?

  3. #3
    Join Date
    Nov 2008
    Posts
    742

    Default

    People ARE unit testing their flows, right? still looking for advice...

  4. #4
    Join Date
    Aug 2004
    Location
    Melbourne, FL
    Posts
    2,794

    Default

    Have you tried configuring a StaticMessageSource on your DefaultMessageContext?

    Keith
    Keith Donald
    Core Spring Development Team

  5. #5
    Join Date
    Nov 2008
    Posts
    742

    Default

    That's one good solution, especially when we're just testing a method that needs to be passed a MessageContext object.

    Originally, when I tried to register a message source in the configureFlowBuilderContext() method like so:'

    Code:
    builderContext.registerBean("messageSource", messageSource);
    I got an exception which said a static message source was already registered.
    Last edited by InverseFalcon; Jun 22nd, 2009 at 02:56 PM. Reason: My proposed solution does not work

  6. #6
    Join Date
    Nov 2008
    Posts
    742

    Default

    Ok, guess I'm not out of the woods yet.

    When I try to resolve a code against the message source, I get this:

    Code:
    org.springframework.context.NoSuchMessageException: No message found under code 'error_char_type_invalid' for locale 'en_US'.
    So, somehow I need to associate the message source (or at least the messages) with the locale.

    So far, all of my attempts to set the message sources or set the parent message sources have failed. I might be able to do something if I can get my hands on the currently registered StaticMessageSource. What's the easiest way to get this so I can modify it?

  7. #7
    Join Date
    Nov 2008
    Posts
    742

    Default

    Found one reason why this wasn't working. I was using ReloadableResourceBundleMessageSource's setBasename() method, but was including the full "messages.properties" name at the end instead of just "messages" like you're supposed to.

  8. #8
    Join Date
    Mar 2008
    Posts
    20

    Angry Any Ideas?

    Hi,

    I'm having the same problem. I see no way of binding my messages.properties to my flow test. To summarize:

    When I try to add a message to the MessageContext at a point in my flow, I get:

    Code:
    org.springframework.context.NoSuchMessageException: No message found under code 'my.code' for locale 'de_DE'.
    as InverseFalcon also stated, when I try to register the messageSource:

    Code:
    builderContext.registerBean("messageSource", messageSource);
    I get:

    Code:
    java.lang.IllegalStateException: Could not register object [org.springframework.context.support.ResourceBundleMessageSource: basenames=[messages]] under bean name 'messageSource': there is already object [org.springframework.context.support.StaticMessageSource: {}] bound
    	at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.registerSingleton(DefaultSingletonBeanRegistry.java:124)
    	at org.springframework.webflow.test.MockFlowBuilderContext.registerBean(MockFlowBuilderContext.java:72)
    	at my.package.MyFlowExecutionIntTest.configureFlowBuilderContext(MyFlowExecutionIntTest.java:50)
    	at org.springframework.webflow.test.execution.AbstractExternalizedFlowExecutionTests.buildFlow(AbstractExternalizedFlowExecutionTests.java:171)
    	at org.springframework.webflow.test.execution.AbstractExternalizedFlowExecutionTests.getFlowDefinition(AbstractExternalizedFlowExecutionTests.java:147)
    	at org.springframework.webflow.test.execution.AbstractFlowExecutionTests.startFlow(AbstractFlowExecutionTests.java:120)
    	at org.springframework.webflow.test.execution.AbstractFlowExecutionTests.startFlow(AbstractFlowExecutionTests.java:109)
    	at my.package.MyFlowExecutionIntTest.testMyFlow(MyFlowExecutionIntTest.java:68)
    	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    	at java.lang.reflect.Method.invoke(Method.java:597)
    	at org.springframework.test.context.junit4.SpringTestMethod.invoke(SpringTestMethod.java:160)
    	at org.springframework.test.context.junit4.SpringMethodRoadie.runTestMethod(SpringMethodRoadie.java:233)
    	at org.springframework.test.context.junit4.SpringMethodRoadie$RunBeforesThenTestThenAfters.run(SpringMethodRoadie.java:333)
    	at org.springframework.test.context.junit4.SpringMethodRoadie.runWithRepetitions(SpringMethodRoadie.java:217)
    	at org.springframework.test.context.junit4.SpringMethodRoadie.runTest(SpringMethodRoadie.java:197)
    	at org.springframework.test.context.junit4.SpringMethodRoadie.run(SpringMethodRoadie.java:143)
    	at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.invokeTestMethod(SpringJUnit4ClassRunner.java:160)
    	at org.junit.internal.runners.JUnit4ClassRunner.runMethods(JUnit4ClassRunner.java:51)
    	at org.junit.internal.runners.JUnit4ClassRunner$1.run(JUnit4ClassRunner.java:44)
    	at org.junit.internal.runners.ClassRoadie.runUnprotected(ClassRoadie.java:27)
    	at org.junit.internal.runners.ClassRoadie.runProtected(ClassRoadie.java:37)
    	at org.junit.internal.runners.JUnit4ClassRunner.run(JUnit4ClassRunner.java:42)
    	at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:97)
    	at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:45)
    	at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
    	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:460)
    	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:673)
    	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:386)
    	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:196)
    The comment:

    Have you tried configuring a StaticMessageSource on your DefaultMessageContext?
    is interesting, but I see no entry points to get the DefaultMessageContext, much less add something to it. Does anyone know a way of doing this?

    When I run the app in container, my messages show up. I would like to use the MessageSource I defined in my applicationContext.xml and confirm that the correct validation message is set.

    Any help or suggestions would be appreciated.
    Last edited by wackydog; Jun 30th, 2009 at 08:40 AM.

  9. #9
    Join Date
    May 2007
    Posts
    14

    Default Solutions?

    Hi there!

    I'm having the exact same problem - has anyone solved this?

    -Kim

  10. #10

    Default Write Your Own MessageSource

    So originally we used a StaticMessageSource approach where we created a message source with all the appropriate codes and then tested against it. That became a pain to maintain and so I took an alternate approach:

    Write your own testMessageSource. Mine looks like this:
    Code:
    public class TestMessageSource extends AbstractMessageSource {
    
        /**
         * Resolve code returns a message with the code and ignores Locale
         * @param code
         * @param locale
         * @return
         */
        protected MessageFormat resolveCode(String code, Locale locale) {
    
            return createMessageFormat(code, locale);
    
        }
    }
    If you use this as your message source, it will always insert a message with the code itself as teh message. So you can do things like:

    Code:
    public void testPhaseIsBlank() throws Exception {
            TestMessageSource source = new TestMessageSource();
            DefaultMessageContext ctx = new DefaultMessageContext(source);
            EditForm epf = new EditForm();
            epf.setPhase(null);
             epf.validateSave(ctx);
            assertMessageExists("editForm.noPhase", ctx);
    }
    
    
     public static void assertMessageExists(String msg, MessageContext msgs) {
    
            for (Message message : msgs.getAllMessages()) {
                if (message.getText().contains(msg)) {
                    return;
                }
            }
    
            Assert.fail("msg '" + msg + "' not found in msgs: " + msgs);
        }
    Obviously, this doesn't test that your messages resource contains the right codes but that's a much more complicated issue (because some messagebuilders might specify default messages, etc.). We actually solve that by code analysis (ie, look for all messagebuilders, find all message codes, make sure they are in the resource file) rather than testing.

    Hope this helps!

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •