I have a message-enricher , inside that I have a call to data base to get sequence value. Here is the component of my flow
<enricher doc:name="Enrich Flow Variable">
<db:select config-ref="LocalhostPostgres" doc:name="Database">
<db:parameterized-query><![CDATA[Select (nextval('batch_id_seq'))]]></db:parameterized-query>
</db:select>
<enrich source="#[payload[0].nextval]" target="#[flowVars.flow_batch_id]" />
<enrich source="#['INPUT_CSV']" target="#[flowVars.flow_source_name]" />
</enricher>
what I want,, in my unit testing I want to mock it so that I can pass constant values to my flow_batch_id.
Is there any way to do it?. Please help me.
I wouldn't mock the enricher. Instead I would mock the db:select to return a sample result. You can either mock the db:select operation, or move the db:select to a sub-flow/private flow and mock that instead. Take a look at the munit mock documentation: https://docs.mulesoft.com/munit/v/1.1.1/mock-message-processor
Related
Have in integration test:
with mock.patch.object(
EmailMultiAlternatives, 'send', autospec=True,
side_effect=EmailMultiAlternatives.send
) as mocked_mail_send:
method_using_that_send()
mocked_mail_send # how to access here send's return value ?
Mocking purpose is to verify if my method will call external method, but I don't want mock entirely that send method and overwrite original return_value.
Found it as impossible to achieve in mock.
Resolved by splitting test to:
unit test with mocked send
integration test testing only result from that external send.
I wonder if anyone can help - this has been driving me crazy for days!
I have a fairly simple Spring Integration file that I'd like to unit test. The SI uses an http outbound gateway, and I specifically want to unit test rather than integration test - I do not want to provide a mock http server using something like Spark or MockRestServiceServer.
My SI config looks like this:
<int:channel id="modifiedAttractionChannel" datatype="u.o.n.p.i.a.s.AttractionUuid">
<int:interceptors>
<int:wire-tap channel="attractionModifiedChannelLogging"/>
</int:interceptors>
</int:channel>
<int-http:outbound-gateway
id="serviceGateway"
request-channel="modifiedAttractionChannel"
url="/attractions/{uuid}"
http-method="GET"
expected-response-type="u.o.n.p.i.a.v.m.Attraction"
charset="UTF-8"
reply-timeout="${vader.reply.timeout}"
request-factory="clientHttpRequestFactory"
reply-channel="vaderAttractionChannel">
<int-http:uri-variable name="uuid" expression="headers['#{T(u.o.n.p.i.a.s.AttractionsImportInitializer).HEADER_UUID}'].value" />
</int-http:outbound-gateway>
<int:channel id="attractionChannel" datatype="u.o.n.p.i.a.v.m.Attraction">
<int:interceptors>
<int:wire-tap channel="vaderAttractionChannelLogging"/>
</int:interceptors>
</int:channel>
<int:logging-channel-adapter
id="attractionModifiedChannelLogging"
expression="'attractionModifiedChannel: header=' + headers['#{T(u.o.n.p.i.a.s.AttractionsImportInitializer).HEADER_UUID}'].value + ', payload=' + payload"
level="INFO" />
<int:logging-channel-adapter
id="vaderAttractionChannelLogging"
expression="'attractionModifiedChannel: header=' + headers['#{T(u.o.n.p.i.a.s.AttractionsImportInitializer).HEADER_UUID}'].value + ', payload=' + payload"
level="INFO" />
I have written a unit test that wires up a basic spring context and am able to get the modifiedAttractionChannel and send an appropriately built Message with an AttractionUuid payload and header value.
My unit test can assert that the log message written to attractionModifiedChannelLogging is as I expect it (I created the AttractionUuid and Message, so I know the payload and header values)
What I now need to do is assert the value written to the vaderAttractionChannelLogging wiretap. IE. I need to assert a message with a given header value - no problem, I created the header value as part of the test - but also the payload.
In this case the payload is the output of the outbound gateway. Given that this is a unit test and I don't want any dependency on anything else, I have provided a mock ClientHttpRequestFactory which in turn provides a mock ClientHttpResponse via a mock ClientHttpRequest
This works great in that I can control the response body that the outbound gateway would otherwise receive. However, the RestTemplate calls its HttpRequestExecutingMessageHandler in order to convert the response body into an object via the MessageConverters
Whilst this works in respect of the execution of the SI flow, it means the instance of Attraction that is on the reply-channel vaderAttractionChannel is not in control of the test; and therefore I cannot make any assertions about it in respect of what gets logged on the vaderAttractionChannelLogging wiretap.
I think one way of addressing this is to be able to wire in a mock or stub MessageConvertor instead of the standard set that returns a fixed Attraction instance. But I can't for the life of me work out how to!
Note: The scenario above is a much simplified version of what I'm actually trying to do. I'm not really trying to write unit tests around logged values! I need to test the overall flow of my SI, and being able to control the instance of the Attraction that the outbound gateway returns is very much key to that.
Any help with this would be very much appreciated;
Cheers
Nathan
It's not clear what your issue is; "...the RestTemplate calls its HttpRequestExecutingMessageHandler..." - it's actually the other way around. If you really want to unit test the flow, you should provide a normal result from the mock that will be converted by the standard converters. If you really want to mock the conversion too, use the message-converters attribute.
I am new to writing test cases for WebAPI's. I have seen similar questions asked in the past, but not answered, but I am wondering how I would test my APIs if they have an ODataQueryOptions as part of the parameters. See below:
public IQueryable<Item> GetByIdAndLocale(ODataQueryOptions opts,
Guid actionuniqueid,
string actionsecondaryid)
Would I have to moq this? If so, how would this look? Any help would be appreciated.
For ODataQueryOptions perspective, you may want to test that all the OData query options can work with your Function. So firstly you need to create an instance of ODataQueryOptions. Here is an example:
HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, requestUri);
ODataQueryContext context = new ODataQueryContext(EdmCoreModel.Instance, elementType);
ODataQueryOptions options = new ODataQueryOptions(context, request);
So you need to create your own EDM model to replace EdmCoreModel.Instance, and replace requestUri with your query. elemntType in ODataQueryContext is "The CLR type of the element of the collection being queried".
I cannot tell from the phrasing, but is the above call (GetByIdAndLocale) the Web API that you are trying to test or are you trying to test something that is calling it?
One uses a mock or a stub to replace dependencies in a Unit Under Test (UUT). If you are testing GetByIdAndLocale() then you would not mock it though if it calls something else that takes the ODataQueryOptions as a parameter, you could use Moq to stub/mock that call.
If you are testing some unit that calls GetByIdAndLocale() then, yes, you could moq it. How exactly you might do this depends upon the goal (checking that the correct values are being passed in vs. checking that the returned IQueryable is correctly processed) basically, matching against It.IsAny() or against some matcher.
Which do you want to test?
GetByIdAndLocale(), something that calls it or something (not shown) that it calls?
What are you interested in verifying?
Correct options are passed in or the processing of the return from the mocked call?
I am trying to get Spring to inject EasyMock mocks in my unit tests.
In my applicationContext.xml, I have this:
<bean id="mockService" class="org.easymock.EasyMock" factory-method="createMock" name="MockService">
<constructor-arg index="0" value="my.project.Service"/>
</bean>
In my unit test I have this:
#Autowired
#Qualifier("mockService")
private Service service;
public void testGetFoo() {
Foo foo = new Foo();
expect(service.findFoo()).andReturn(foo);
replay(service); // <-- This is line 45, which causes the exception
// Assertions go here...
}
When I try to run my test, I get this stack trace:
java.lang.ClassCastException: org.springframework.aop.framework.JdkDynamicAopProxy
at org.easymock.EasyMock.getControl(EasyMock.java:1330)
at org.easymock.EasyMock.replay(EasyMock.java:1279)
at TestFooBar.testGetFoo(TestVodServiceLocator.java:45)
I am quite new to both Spring and EasyMock, but it seems to me that the error is caused by EasyMock trying to call a method on what it assumes to be an instance of EasyMock, but is in reality a dynamic proxy created by Spring. As I understand it, dynamic proxies only implement the methods defined in the interface, in this case the interface for Service.
What I don't understand is that from what I read (also here), what I'm trying to achieve at least seems to be possible.
So my question is: What I'm I not doing or what am I doing wrong?
You can also create a helper method to unwrap the EasyMock proxy from the Spring proxy to define expected behaviour then:
public static <T> T unwrap(T proxiedInstance) {
if (proxiedInstance instanceof Advised) {
return unwrap((T) ((Advised) proxiedInstance).getTargetSource().getTarget());
}
return proxiedInstance;
}
Note the recusive call as in worst case you have multiple proxies wrapped around the actual target.
Solved!
I had overlooked this in my applicationContext.xml:
<bean id="txProxyAutoCreator" class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">
<property name="beanNames">
<list>
<value>*Service</value>
<!-- ^^^^^^^^
This is the problem!
-->
</list>
</property>
<property name="interceptorNames">
<list>
<value>txAdvisor</value>
</list>
</property>
</bean>
... which causes Spring to automatically create proxy objects for all beans with names that end in "Service".
My solution was to explicitly list the beans instead of using a wild card. This seems a little brittle to me, however, so if anyone knows how to specify all *Service beans except FooService, I would be grateful.
Something's odd here. You're clearly quickly mastering both Spring and EasyMock. The autoproxies, the factory methods, all good signs that you're diving deep into Spring's capabilities.
Still, it's kind of odd that you're injecting a mock bean into a class at all. You may have a great reason, but to me it's a code smell. I'd advise you to consider only wiring in real services into your test classes and then initializing the mock objects as needed. Why spend 3 lines in java and another 3 lines in XML (plus 1 line to reset them) to create a mock object with no dependencies? Just say Service service = (Service)createMock(Service.class). I would advise creating them in the methods that you need them for, set expectations, inject, use them, and then discard them. In your model, you'll have to remember to reset the mock object every time you use it, which is less clear than just creating a new one.
Of course, this is a style issue and not a correctness issue, so ignore as desired.
I know this question is old, but I just stumbled upon it searching for a similar problem.
The problem is that Spring doesn't know the type of the mock object. The method you use looks like this:
public static <T> T createMock(final Class<T> toMock) {
return createControl().createMock(toMock);
}
Spring isn't smart enough to derive T from the constructor argument (at least the last time I've checked), so it thinks the returned object is of type java.lang.Object. As a consequence, the created proxy doesn't implement my.project.Service and therefore can't be injected.
The answer therefore is to tell Spring the required type.
I'm implementing a client consuming a webservice. I want to reduce dependencies and decided to mock the webservice.
I use mockito, it has the advantage vs. EasyMock to be able to mock classes, not just interfaces. But that's not the point.
In my test, I've got this code:
// Mock the required objects
Document mDocument = mock(Document.class);
Element mRootElement = mock(Element.class);
Element mGeonameElement = mock(Element.class);
Element mLatElement = mock(Element.class);
Element mLonElement = mock(Element.class);
// record their behavior
when(mDocument.getRootElement()).thenReturn(mRootElement);
when(mRootElement.getChild("geoname")).thenReturn(mGeonameElement);
when(mGeonameElement.getChild("lat")).thenReturn(mLatElement);
when(mGeonameElement.getChild("lon")).thenReturn(mLonElement);
// A_LOCATION_BEAN is a simple pojo for lat & lon, don't care about it!
when(mLatElement.getText()).thenReturn(
Float.toString(A_LOCATION_BEAN.getLat()));
when(mLonElement.getText()).thenReturn(
Float.toString(A_LOCATION_BEAN.getLon()));
// let it work!
GeoLocationFetcher geoLocationFetcher = GeoLocationFetcher
.getInstance();
LocationBean locationBean = geoLocationFetcher
.extractGeoLocationFromXml(mDocument);
// verify their behavior
verify(mDocument).getRootElement();
verify(mRootElement).getChild("geoname");
verify(mGeonameElement).getChild("lat");
verify(mGeonameElement).getChild("lon");
verify(mLatElement).getText();
verify(mLonElement).getText();
assertEquals(A_LOCATION_BEAN, locationBean);
What my code shows is that I "micro-test" the consuming object. It's like I would implement my productive code in my test. An example for the result xml is London on GeoNames.
In my opinion, it's far too granular.
But how can I mock a webservice without giving everystep? Should I let the mock object just return a XML file?
It's not about the code, but the approach.
I'm using JUnit 4.x and Mockito 1.7
I think the real problem here is that you have a singleton that calls and creates the web service so it is difficult to insert a mock one.
You may have to add (possibly package level) access to the singleton class. For example if the constructor looks something like
private GeoLocationFactory(WebService service) {
...
}
you can make the constructor package level and just create one with a mocked web service.
Alternatively you can set the webservice by adding a setter method, although I don't like mutable Singletons. Also in that case you have to remember to unset the webservice afterwards.
If the webservice is created in a method you might have to make the GeoLocationFactory extensible to substitute the mock service.
You may also look into remove the singleton itself. There are articles online and probably here on how to do that.
you really want to be mocking the results returned from the webservice to the code that will be using the result. In your example code above you seem to be mocking mDocument but you really want to pass in an instance of mDocument that has been returned from a mocked instance of your webservice and assert that the locationBean returned from the geoLocationFetcher matches the value of A_LOCATION_BEAN.
The easiest option would be to mock the WebService client,
when(geoLocationFetcher.extractGeoLocationFromXml(anyString()))
.thenReturn("<location/>");
You can modify the code to read the response xml from the file system.
Sample code can be found here: Mocking .NET WebServices with Mockito