Testing with Clock - spring-test

Is it possible to have an instance of Clock being configured per test class?
Problem is that Clock of the current test is being overwritten by the configuration of another test.
I'm configuring my tests like bellow:
public class ClockTestCase extends AbstractTestCase {
#Configuration
static class ContextConfiguration {
#Bean
#Primary
Clock fixedClock() {
LocalDateTime fixed = ...
return Clock.fixed(fixed.toInstant(ZoneOffset.of(AMERICA_SAO_PAULO_OFFSET_ID)), ZoneId.systemDefault());
}
}
#Test
public void test() throws Exception {
// Act and Assert
this.mvc()
.perform(put(MY_URL, 1))
.andDo(print())
.andExpect(status().isNotFound());
}
}

Related

How to use the mock object of the test class and call main method from the test class

In the test class trying to test the main method and not sure how to use the mock object here.
How to use the mock object orders to call the main method and it's methods inside the main method
Any suggestions on how this can be done?
public class Orders {
public static void main(String[] s) {
Orders jp = new Orders();
jp.method1();
List<OrderItems> lstOrdItms = jp.getListOrderItems();
jp.processOrderItems( lstOrdItms );
}
public void method1(List<OrderItem> lstOrderItem) {
.........
}
public List<OrderItem> getListOrderItems() {
............
}
public void processOrderItems() {
............
}
}
public class OrdersTest {
#Mocks
Orders orders;
.....
#Before
public void setUp() {
........
}
#Test
public void testMain() throws SQLException {
// Not sure how to test here
// This will actually execute the main method instead of mock.
orders.main(new String[]{});
}
}

How to implement distributed lock around poller in Spring Integration using ZooKeeper

Spring Integration has ZooKeeper support as documented in https://docs.spring.io/spring-integration/reference/html/zookeeper.html
However this document is so vague.
It suggests adding below bean but does not give details on how to start/stop a poller when the node is granted leadership.
#Bean
public LeaderInitiatorFactoryBean leaderInitiator(CuratorFramework client) {
return new LeaderInitiatorFactoryBean()
.setClient(client)
.setPath("/siTest/")
.setRole("cluster");
}
Do we have any example on how to ensure below poller is run only once in a cluster at any time using zookeeper?
#Component
public class EventsPoller {
public void pullEvents() {
//pull events should be run by only one node in the cluster at any time
}
}
The LeaderInitiator emits an OnGrantedEvent and OnRevokedEvent, when it becomes leader and its leadership is revoked.
See https://docs.spring.io/spring-integration/reference/html/messaging-endpoints-chapter.html#endpoint-roles and the next https://docs.spring.io/spring-integration/reference/html/messaging-endpoints-chapter.html#leadership-event-handling for more info about those events handling and how it affects your components in the particular role.
Although I agree that Zookkeper chapter must have some link to that SmartLifecycleRoleController chapter. Feel free to raise a JIRA on the matter and contribution is welcome!
UPDATE
This is what I did in our test:
#RunWith(SpringRunner.class)
#DirtiesContext
public class LeaderInitiatorFactoryBeanTests extends ZookeeperTestSupport {
private static CuratorFramework client;
#Autowired
private PollableChannel stringsChannel;
#BeforeClass
public static void getClient() throws Exception {
client = createNewClient();
}
#AfterClass
public static void closeClient() {
if (client != null) {
client.close();
}
}
#Test
public void test() {
assertNotNull(this.stringsChannel.receive(10_000));
}
#Configuration
#EnableIntegration
public static class Config {
#Bean
public LeaderInitiatorFactoryBean leaderInitiator(CuratorFramework client) {
return new LeaderInitiatorFactoryBean()
.setClient(client)
.setPath("/siTest/")
.setRole("foo");
}
#Bean
public CuratorFramework client() {
return LeaderInitiatorFactoryBeanTests.client;
}
#Bean
#InboundChannelAdapter(channel = "stringsChannel", autoStartup = "false", poller = #Poller(fixedDelay = "100"))
#Role("foo")
public Supplier<String> inboundChannelAdapter() {
return () -> "foo";
}
#Bean
public PollableChannel stringsChannel() {
return new QueueChannel();
}
}
}
And I have in logs something like this:
2018-12-14 10:12:33,542 DEBUG [Curator-LeaderSelector-0] [org.springframework.integration.support.SmartLifecycleRoleController] - Starting [leaderInitiatorFactoryBeanTests.Config.inboundChannelAdapter.inboundChannelAdapter] in role foo
2018-12-14 10:12:33,578 DEBUG [Curator-LeaderSelector-0] [org.springframework.integration.support.SmartLifecycleRoleController] - Stopping [leaderInitiatorFactoryBeanTests.Config.inboundChannelAdapter.inboundChannelAdapter] in role foo

in BeforeClass method how to insert init data to db

I have a UserServiceTest, I want to init load some user data to database for tests e.g. queryByName, groupByAge and so on . And I want to only load once in this class, so I want to use BeforeClass
#BeforeClass
public static void init(){
// ...
}
but in this case I find I cannot use jdbcTemplate to insert data just like in Before e.g.
#Before
public void setUp(){
// prepare test data first
jdbcTemplate.execute("insert into user(firstname,lastname,birthday) values(...);");
}
So in BeforeClass method how to insert init data?
Alternatively you can use TestExecutionListeners in order to initialise your database before test class.
#RunWith(SpringJUnit4ClassRunner.class)
#ContextConfiguration(classes = TestConfig.class)
#TestExecutionListeners(mergeMode = TestExecutionListeners.MergeMode.MERGE_WITH_DEFAULTS, listeners = {
DbInitializerTestListener.class })
public class DbTest {
}
public class DbInitializerTestListener extends AbstractTestExecutionListener {
#Autowired
private JdbcTemplate jdbcTemplate;
#Override
public void beforeTestClass(TestContext testContext) throws Exception {
testContext.getApplicationContext()
.getAutowireCapableBeanFactory()
.autowireBean(this);
jdbcTemplate.execute("insert into user(firstname,lastname,birthday) values(...);");
}
}
Or you may consider DbUnit framework.

MS TEst: Method not executed when base class is generic

Not duplicate of: Inherited test class from generic base is ignored in MSTest
In my case, the test classes are in the same namespace/assembly.
When unittesting classes which have a lot in common, I would like to use a base test class with a generic parameter. I have boiled the problem down to the following, where my base test method is not being executed, but ONLY in the generic case.
Non-generic: Base test method is EXECUTED:
[TestClass]
public class DerivedTestClass : BaseUnitTest
{
protected override string ReturnMeSomething(object obj)
{
return "test1" + obj.ToString();
}
[TestMethod]
public void derived_test()
{
// This is executed
}
}
[TestClass]
public abstract class BaseUnitTest
{
[TestMethod]
public void base_test()
{
// This is executed
}
protected abstract string ReturnMeSomething(object obj);
}
Generic: Base test method in generic base class is NOT EXECUTED:
[TestClass]
public class DerivedTestClass : BaseUnitTest<string>
{
protected override string ReturnMeSomething(string s)
{
return "test1" + s;
}
[TestMethod]
public void derived_test()
{
// This is executed
}
}
[TestClass]
public abstract class BaseUnitTest<T>
{
[TestMethod]
public void base_test()
{
// This is NOT executed
}
protected abstract string ReturnMeSomething(T t);
}
Can anyone tell me the reason for this?
After a few days, this suddenly works (!!). If anyone ever experiences this same, odd behavior, please write a comment here. I would suggest anyone to reboot and clean+rebuild everything and try again.

Postsharp - Adding OnMethodBoundaryAspect to abstract Method - Aspect Not Firing

I'm trying to implement an OnMethodBoundary aspect on an abstract method in an abstract class so that all types that inherit from this class will automatically have the aspect applied. There are no compilation errors or warnings, but the OnEntry method doesn't fire. Note: If I apply the aspect to a non-abstract method, everything works fine
here's the aspect example:
[Serializable]
[MulticastAttributeUsage(MulticastTargets.Method, Inheritance = MulticastInheritance.Multicast)]
public sealed class DoSomethingAttribute : OnMethodBoundaryAspect
{
public override void OnEntry(MethodExecutionArgs args)
{
//Do work
}
}
// here's the abstract class
public abstract class Job
{
//...
[DoSomething]
public abstract void Run();
}
Updated answer: it doesn't matter where anything is, as long as both projects have Postsharp referenced then you're good to go.
It works just fine. Which version of PostSharp are you using?
class Program
{
static void Main(string[] args)
{
Job1 j = new Job1();
j.Run();
Console.ReadKey();
}
}
[Serializable]
[MulticastAttributeUsage(MulticastTargets.Method, Inheritance = MulticastInheritance.Multicast)]
public sealed class DoSomethingAttribute : OnMethodBoundaryAspect
{
public override void OnEntry(MethodExecutionArgs args)
{
Console.WriteLine("OnEntry");
}
}
public abstract class Job
{
//...
[DoSomething]
public abstract void Run();
}
public class Job1 : Job
{
public override void Run()
{
Console.WriteLine("Run method");
}
}
Results:
OnEntry
Run method

Resources