Reactive java test (StepVerifier) - testing

I would like to write a test for the piece of code below. Specially I would like to verify the existence of the "response" object. Can I achieve this using "StepVerifier"?
saharaSnowTickets.raiseIncidentWithCustomDescriptionAndNonRandomEventId(summary, description,
Severity.SEV_2,
cmdId
).retryWhen(Retry.backoff(properties.getRetry(), getDuration(properties.getUnity(), properties.getDuration())))
.doOnNext(response -> {log.info("response {}", response) })
.then();

Related

How to test #type decorator in NestJs using jest? [duplicate]

I am asking you for help. I have created a DTO that looks like it (this is a smaller version) :
export class OfImportDto {
#IsString({
message: "should be a valid product code"
})
productCode: string;
#IsString({
message: "Enter the proper product description"
})
productDescription: string;
#IsDateString({
message: "should be a valid date format, for example : 2017-06-07T14:34:08+04:00"
})
manufacturingDate : Date
#IsInt({
message: "should be a valid planned quantity number"
})
#IsPositive()
plannedQuantity: number;
the thing is that i am asking to test that, with a unit test and not a E2E test. And I Don't know how to do that. For instance, I would like to unit test
1/ if my product code is well a string, a string should be created, if not, throw my exception
2/ if my product description is well a string, a string should be created, if not, throw my exception
...
and so on.
So, can I made a spec.ts file to test that? If yes, how?
If not, is it better to test it within the service.spec.ts? If so, how?
Thank you very much, any help would be very helpful :)
You should create a separate DTO specific file like of-import.dto.spec.ts for unit tests of your DTOs. Let's see how to test a DTO in Nest.js step by step.
TLDR: Your DTO's unit test
To understand it line by line, continue reading:
it('should throw when the planned quantity is a negative number.', async () => {
const importInfo = { productCode: 4567, plannedQuanity: -10 }
const ofImportDto = plainToInstance(OfImportDto, importInfo)
const errors = await validate(ofImportDto)
expect(errors.length).not.toBe(0)
expect(stringified(errors)).toContain(`Planned Quantity must be a positive number.`)
}
Create a plain object to test
The following is an object that you would like to test for validation:
const importInfo = { productCode: 4567, plannedQuanity: -10 }
If your test object has nested objects or it's too big, you can skip those complex properties. We'll see how to deal with that.
Convert the test object to the type of DTO
Use plainToinstace() function from the class-transformer package:
const ofImportDto = plainToInstance(OfImportDto, importInfo)
This will turn your plain test object to the object of the type of your DTO, that is, OfImportDto.
If you have any transformations in your DTO, like trimming spaces of the values of properties, they are applied at this point. If you just intend to test the transformations, you can assert now, you don't have to call the following validate() function for testing transformations.
Emulate the validation
Use the validate() function from the class-validator package:
const errors = await validate(ofImportDto)
If you skipped some properties while creating the test object, you can deal with that like the following:
const errors = await validate(ofImportDto, { skipMissingProperties: true })
Now the validation will ignore the missing properties.
Assert the errors
Assert that the errors array is not empty and it contains your custom error message:
expect(errors.length).not.toBe(0)
expect(stringified(errors)).toContain(`Planned Quantity must be a positive number.`)
Here stringified() is a helper function to convert the errors object to a JSON string, so we can search if it contains our custom error message:
export function stringified(errors: ValidationError[]): string {
return JSON.stringify(errors)
}
That's it! Hope that helps.
It would be possible to create a OfImportDTO.spec.ts file (or whatever your original file is called), but the thing is, there isn't any logic here to test. The closest thing you could do is create an instance of a Validator from class-validator and then instantiate an instance of the OfImportDto and then check that the class passes validation. If you add logic to it (e.g. getters and setters with specific functions) then it could make sense for unit testing, but otherwise, this is basically an interface being called a class so it exists at runtime for class-validator

Extracting Nested POJO Object with Rest-Assured

I'm writing some tests using rest-assured and its Kotlin extensions to test some simple Spring MVC endpoints. I'm trying to understand how to extract values.
One endpoint returns a BookDetailsView POJO, the other returns a Page<BookDetailsView> (where Page is an interface provided by Spring for doing paging).
BookDetailsView is a really simple Kotlin data class with a single field:
data class BookDetailsView(val id: UUID)
For the single object endpoint, I have:
#Test
fun `single object`() {
val details = BookDetailsView(UUID.randomUUID())
whenever(bookDetailsService.getBookDetails(details.id)).thenReturn(details)
val result: BookDetailsView = Given {
mockMvc(mockMvc)
} When {
get("/book_details/${details.id}")
} Then {
statusCode(HttpStatus.SC_OK)
} Extract {
`as`(BookDetailsView::class.java)
}
assertEquals(details.id, result.id)
}
This works as expected, but trying to apply the same technique for the Page<BookDetailsView> runs afoul of all sorts of parsing challenges since Page is an interface, and even trying to use PageImpl isn't entirely straightforward. In the end, I don't even really care about the Page object, I just care about the nested list of POJOs inside it.
I've tried various permutations like the code below to just grab the bit I care about:
#Test
fun `extract nested`() {
val page = PageImpl(listOf(
BookDetailsView(UUID.randomUUID())
))
whenever(bookDetailsService.getBookDetailsPaged(any())).thenReturn(page)
val response = Given {
mockMvc(mockMvc)
} When {
get("/book_details")
} Then {
statusCode(HttpStatus.SC_OK)
body("content.size()", `is`(1))
body("content[0].id", equalTo(page.first().id.toString()))
} Extract {
path<List<BookDetailsView>>("content")
}
println(response[0].javaClass)
}
The final println spits out class java.util.LinkedHashMap. If instead I try to actually use the object, I get class java.util.LinkedHashMap cannot be cast to class BookDetailsView. There are lots of questions and answers related to this, and I understand it's ultimately an issue of the underlying JSON parser not knowing what to do, but I'm not clear on:
Why does the "simple" case parse without issue?
Shouldn't the type param passed to the path() function tell it what type to use?
What needs configuring to make the second case work, OR
Is there some other approach for grabbing a nested object that would make more sense?
Digging a bit into the code, it appears that the two cases may actually be using different json parsers/configurations (the former seems to stick to rest-assured JSON parsing, while the latter ends up in JsonPath's?)
I don't know kotlin but here is the thing:
path() doesn't know the Element in your List, so it'll be LinkedHashMap by default instead of BookDetailsView.class
to overcome it, you can provide TypeReference for this.
java example
List<BookDetailsView> response = ....then()
.extract().jsonPath()
.getObject("content", new TypeRef<List<BookDetailsView>>() {});
kotlin example
#Test
fun `extract nested`() {
var response = RestAssured.given().get("http://localhost:8000/req1")
.then()
.extract()
.jsonPath()
.getObject("content", object : TypeRef<List<BookDetailsView?>?>() {});
println(response)
//[{id=1}, {id=2}]
}

How to make a MultiMock Http Callout Test for Salesforce?

If I have an Apex function that is named authorize() that just gets a username, password, and session token, and another function called getURL('id#', 'key'), that takes an id# for the record as a string and a key for the image to return as a string as parameters. getURL calls the authorize function inside it in order to get the credentials for its callout. The authorize is a post request, and the getURL is a get request.
I am trying to figure out how to test both of these callouts just so I can make sure that getURL is returning the proper JSON as a response. It doesn't even have to be the URL yet which is its intention eventually. But I just need to test it to make sure these callouts are working and that I am getting a response back for the 75% code coverage that it needs.
I made a multiRequestMock class that looks like this:
public class MultiRequestMock implements HttpCalloutMock {
Map<String, HttpCalloutMock> requests;
public MultiRequestMock(Map<String, HttpCalloutMock> requests) {
this.requests = requests;
}
public HTTPResponse respond(HTTPRequest req) {
HttpCalloutMock mock = requests.get(req.getEndpoint());
if (mock != null) {
return mock.respond(req);
} else {
throw new MyCustomException('HTTP callout not supported for test methods');
}
}
public void addRequestMock(String url, HttpCalloutMock mock) {
requests.put(url, mock);
}
}
I then began to write a calloutTest.cls file but wasn't sure how to use this mock class in order to test my original functions. Any clarity or assistance on this would be helpful Thank you.
I believe in your calloutTest class you use Test.setMock(HttpCalloutMock.class, new MultiRequestMock(mapOfRequests)); then call the getUrl and/or authorize methods and instead of the request really executing the response returned will be that which is specified in the response(HttpRequest) method you have implemented in the MultiRequestMock class. That is basically how I see it working, for more info and an example you can see this resource on testing callout classes. This will get you the code coverage you need but unfortunately cannot check you are getting the correct JSON response. For this, you may be able to use the dev console and Execute Anonymous?
You may want to look at simplifying your HttpCalloutMock Implementation and think about removing the map from the constructor as this class really only needs to return a simple response then your calloutTest class can be where you make sure the returned response is correct.
Hope this helps

Reading parameters from TestNG file

I successfully implemented several tests within TestNG framework, where parameters are being read from xml file.
Here is the example block that is executed as first:
#Parameters({ "country" })
#BeforeSuite(alwaysRun = true)
public void prepareRequest(String country, ITestContext cnt) {
LoginInfoRequestParm loginParms = new LoginInfoRequestParm(country);
Headers reqHeaders = new Headers();
reqHeaders.setHeaders(loginParms);
}
The problem/question is, why does it work only if the ITestContext is specified? Once it is removed, the overall suite is broken and it will never come to the specified method prepareRequest(). I was not able to debug it, because I cannt set breakpoint before the method to be able to see what is going on in TestNG itself.
Thank you for your explanation.
To get out of this situation, try something like this
String myPar = context.getCurrentXmlTest().getParameter("country");
if (myPar == null) {
myPar = "INDIA";
}
now myPar can be used, only thing here is if you run class for debug or any other purpose then we are using INDIA. if we run from testng.xml file then it will take values from that file.

How to unit or integration test use of injected messageSource for i18n in Grails 2.0 service

I make use of a message bundle in one of my services in a Grails 2.0 project for internationalized text. The use case is an email subject that is sent via the mail plugin in an asynchronous way, so it really doesn't make sense to have this in a controller or TagLib (given the usual argument of not accessing your text or views in a service). This code works fine in my running Grails app, but I'm not sure how to test it.
I tried a PluginAwareResourceBundleMessageSource in my defineBeans as that is what my running application injects, but it led to nullpointers as it appears it needs a bunch of setup around plugin managers and such that my test environment is not giving (even integration).
I then tried a ReloadableResourceBundleMessageSource as it was pure Spring, but it can't seem to see my .properties files, and fails with a No message found under code 'my.email.subject' for locale 'en'.
I feel like I'm going down a wormhole a bit as accessing Grails i18n in a service is not documented in the grails docs, so if there is a preferred way to do this, let me know.
Note my .properties file is in the standard grails-app/i18n location.
The test
#TestFor(EmailHelperService)
class EmailHelperServiceTests {
void testSubjectsDefaultLocale() {
defineBeans {
//messageSource(PluginAwareResourceBundleMessageSource); Leads to nullpointers
messageSource(ReloadableResourceBundleMessageSource);
}
String expected = "My Expected subject Passed1 Passed2";
String actual = service.getEmailSubjectForStandardMustGiveGiftFromBusiness(Locale.ENGLISH, Passed1 Passed2);
assertEquals("email subject", expected, actual);
}
Service:
class EmailHelperService {
def messageSource;
public String getEmailSubject(Locale locale, String param1, String param2) {
Object[] params = [param1, param2].toArray();
return messageSource.getMessage("my.email.subject", params, locale );
}
There is already a messageSource in unit tests in Grails, it is a StaticMessageSource (see http://static.springsource.org/spring/docs/2.5.4/api/org/springframework/context/support/StaticMessageSource.html), you can add mock messages with the addMessage method:
messageSource.addMessage("foo.bar", request.locale, "My Message")
In unit tests and the local side of functional tests, sometimes you want the real properties that are in the 18n directory.
This works for me:
MessageSource getI18n() {
// assuming the test cwd is the project dir (where application.properties is)
URL url = new File('grails-app/i18n').toURI().toURL()
def messageSource = new ResourceBundleMessageSource()
messageSource.bundleClassLoader = new URLClassLoader(url)
messageSource.basename = 'messages'
messageSource
}
i18n.getMessage(key, params, locale)
In a unit test you could ensure that you're wired up correctly by doing something like this:
void testSubjectsDefaultLocale() {
def messageSource = new Object()
messageSource.metaClass.getMessage = {subject, params, locale ->
assert "my.email.subject" == subject
assert ["Passed1", "Passed2"] == params
assert Locale.ENGLISH == locale
"It Worked!!!"
}
service.messageSource = messageSource
String actual = service.getEmailSubjectForStandardMustGiveGiftFromBusiness(Locale.ENGLISH, Passed1 Passed2)
assert "It Worked!!!" == actual
}
This will help ensure that you're wired up correctly but it will not ensure that what you're doing actually works. If you're comfortable with that then this would work for you. If you're trying to test that when you give "XYZ" to your .properties file it returns "Hello" then this will not work for you.