I've seen while I init and manufactor Pojo's in the multiple Unit tests that the Instance of pojo is the same, how can I get init different Instance for each Test .
/Init PodamFactory
PodamFactory podamFactory = new PodamFactoryImpl();
//Define Strategy to exclude some fields
DefaultClassInfoStrategy classInfoStrategy = DefaultClassInfoStrategy.getInstance();
Related
I am testing a service which heavily relies on project reactor.
For many tests I am mocking the return value of the component responsible for API calls.
The tests are split over multiple files.
When I run the tests of one file, they are green, but when I execute all of the test files at once, some tests fail, with the error message indicating that the mocking did not succeed (Either the injected component returned null, or the implementation of the actual component is invoked).
In the logs, there is no information about the mocking failing.
A code example:
interface API {
Flux<Bird> getBirds();
}
#Component
class BirdWatcher {
API api;
BirdWatcher(API api) {
this.api = api;
}
Flux<Bird> getUncommonBirds() {
return api.getBirds() // Although this is mocked in the test, in some runs it returns `null` or calls the implementation of the actual component
.filter(Bird::isUncommon);
}
}
#SpringBootTest
class BirdWatcherTests {
#Autowired
BirdWatcher birdWatcher;
#MockBean
API api;
#Test
void findsUncommonBirds() {
// Assemble
Bird birdCommon = new Bird("Sparrow", "common");
Bird birdUncommon = new Bird("Parrot", "uncommon");
Mockito.when(api.getBirds()).thenReturn(Flux.just(birdCommon, birdUncommon));
// Act
Flux<Bird> uncommonBirds = birdWatcher.getUncommonBirds();
// Assert
assertThat(uncommonBirds.collectList().block().size(), equalTo(1));
}
}
For me the issue seems like a race condition, but I don't know where and how this might happen, and how I can check and fix this.
I am using spring-boot-test:2.7.8, pulling in org.mockito:mockito-core:4.5.1 org.mockito:mockito-junit-jupiter:4.5.1, and org.junit.jupiter:junit-jupiter:5.8.2, with gradle 7.8.
For reactor, spring-boot-starter-webflux:2.7.8, depending on reactor:2.7.8.
I'm trying to create an integration test in spring boot which should give me a circuit breaker that uses some configs that I specify but for some reason it gives me one with default configs and I don't understand why :(
The test looks like this:
#SpringBootTest(
classes = [
AmericiumApi::class,
AmericiumClient::class,
RetrofitConfig::class,
HttpConnectorListener::class,
TestMetricsConfig::class,
Info4cProperties::class,
InMemoryCircuitBreakerRegistry::class,
CircuitBreakerRegistry::class
],
properties = [
"test.api.url=http://localhost:\${wiremock.server.port}",
"resilience4j.circuitbreaker.configs.default.register-health-indicator=false",
"resilience4j.circuitbreaker.configs.default.sliding-window-size=10",
"resilience4j.circuitbreaker.configs.default.sliding-window-type=COUNT_BASED",
"resilience4j.circuitbreaker.configs.default.failure-rate-threshold=50",
"resilience4j.circuitbreaker.configs.default.minimum-number-of-calls=10",
"resilience4j.circuitbreaker.configs.default.slow-call-duration-threshold=3000",
"resilience4j.circuitbreaker.configs.default.slowCallRateThreshold=100",
"resilience4j.circuitbreaker.configs.default.wait-duration-in-open-state=3000",
"resilience4j.circuitbreaker.configs.default.automatic-transition-from-open-to-half-open-enabled=true",
"resilience4j.circuitbreaker.configs.default.permitted-number-of-calls-in-half-open-state=5",
]
)
#AutoConfigureWireMock(port = 0)
class TestWiremockIntegrationTest {
Do I need to load other classes in the context?
I've seen many examples about Groovy objects as Spring beans but not vice versa. I'm using Groovy in a Java EE application like this:
GroovyCodeSource groovyCodeSource = new GroovyCodeSource(urlResource);
Class groovyClass = loader.parseClass(groovyCodeSource, false);
return (GroovyObject) groovyClass.newInstance();
In this way, classes written in Groovy with #Configurable annotation are being injected with Spring beans. It's OK for now.
How can I get the same by using GroovyScriptEngine? I don't want to define a class and I want it to work like a plain script. Is Spring/Groovy capable of that?
I've seen a post about this but I'm not sure whether it answers my question or not:
HERE
Do you mean that you'd like to add properties to the script, and inject those? Would you provide getter and setter? This does not make much sense to me. What makes sense, is adding the mainContext to the bindings of the script, or adding selected beans to the bindings.
These beans - or the context - would then be accessible directly in the script, as if it was injected.
def ctx = grailsApplication.mainContext
def binding = new Binding([:])
Map variables = [
'aService',
'anotherService'
].inject([config:grailsApplication.config, mainContext:ctx]) { m, beanName ->
def bean = ctx.getBean(beanName)
m[beanName] = bean
m
}
binding.variables << variables
def compiler = new CompilerConfiguration()
compiler.setScriptBaseClass(baseScriptClassName)
def shell = new GroovyShell(new GroovyClassLoader(), binding, compiler)
script=shell.parse(scriptStr)
script.binding=binding
script.init()
script.run()
This question already exists in a way, but the existing question is missing some important links.
I'm trying to move the configuration of beans for my tests into separate files that end in *TestsSpringBeans.groovy
I've attempted to do this after reading "Loading Bean Definitions from the File System" (search for it) in the Groovy documentation.
Here are the relevant code segments:
import grails.util.*
beans = {
...
switch(Environment.current) {
case Environment.TEST:
loadBeans("classpath:*TestsSpringBeans.groovy")
break
}
}
resources.groovy - Loading the *TestSpringBeans files from the File System.
somePlace(jobdb.Company) {
name = "SomeCompany"
addr1 = "addr1"
addr2 = "addr2"
city = "city"
email = "somedude#h0tmail.com"
fax = "555-555-5555"
phone = "444-444-4444"
state = "PA"
zip = "19608"
version: 0
created = new Date()
updated = new Date()
website = "http://www.yahoo.com"
deleted = false
}
CompanyServiceTestsSpringBeans.groovy - Defining a bean for the Integration Test
// Retrieve configured bean from
Company someplace = ApplicationHolder.getApplication().getMainContext().getBean('somePlace')
CompanyServiceTests.groovy - Obtain the bean somePlace within the Integration Test...
Upon calling getBean('somePlace') within the test an error is displayed which reads that No bean named 'somePlace' is defined
The CompanyServiceTests.groovy file is stored with my integration tests, should I be storing this file somewhere else in the project directory structure?
Since your tests run in a way that using the classpath as a reference point is less important, you might try to load the beans { ... } file by referencing via project directory specific path. (e.g. $baseDir/test/resources/MyCustomBeans.groovy) or load the beans explicitly in your tests via #BeforeClass if you are using JUnit4 annotations:
def bb = new BeanBuilder()
def resource = new FileSystemResource('src/test/resources/testContext.groovy')
bb.loadBeans(resource)
appCtx = bb.createApplicationContext()
...
I've got a controller class which accpets multiple parameters in the ctor which gets injected at runtime.
Example:
public ProductController(IProductRepositort productRepository,
IShippingService shippingService, IEmailProvider emailProvider)
{
...
}
I am finding that the Test methods are getting huge. I am setting up the methods as follows:
[Test]
public void CanSendProduct()
{
//Code to set up stub
List<Product> products = new List<Product>();
for (int i = 0; i < length; i++)
{
products.Add(new Product()));
}
var mockProductRepository = new Mock<IProductRepository>();
mockProductRepository.Setup(x => x.GetProducts()).Returns(products);
//Code to set up stub
....
....
var mockShippingService = new Mock<IShippingService>();
mockShippingService.Setup(x => x.GetShippers()).Returns(shippers);
//Code to set up stub
.....
.....
var mockEmailProvider = new Mock<IEmailProvider>();
mockEmailProvider.Setup(x => x.Send()).Returns(provider);
//Execute Test
....
....
//Assert
....
....
}
Obviously, it not practical to repeat the mock setup in every method of this test class.
How can i create rich mocking objects that enables me to do Behavioural verification of my tests and at the same time minimise the setup pain?
What are the TDD best practices to deal with this problem?
Thanks
If your test framework supports setup/teardown functions that will be called before and after each test, create and destroy some "default" mock objects in those functions. Your tests can simply use those, and for special cases where the default mock objects don't work for you, you can simply ignore them and create local mock objects within those tests.
Use a Behavioural, or functional testing suite. Looks like your in C# or Java? Either way I would recommend FItnesse but there are others. As for the unit tests, I would probably use a IOC container like Winsor/Castle or Spring, then you can set up a container for the tests thats filled with Mocks rather than "real" objects.
I'd just extract this code into methods (if your mock framework requires you to pass the mock factory in, change the signature as needed):
private Mock<IProductRepository> SetupStandardMockProductRepository() {
List<Product> products = new List<Product>();
for (int i = 0; i < length; i++) {
products.Add(new Product()));
}
var mockProductRepository = new Mock<IProductRepository>();
mockProductRepository.Setup(x => x.GetProducts()).Returns(products);
}
// ... and so forth
Then, in your tests:
var mockProductRepository = SetupStandardMockProductRepository();
// or make these static properties of some central test class, like this:
var mockProductRepository = Stubs.StandardProductRepository;