I'm playing with a simple handler that implements IWantToRunWhenBusStartsAndStops and in the start, it schedules a task like so:
public void Start()
{
_schedule.Every(TimeSpan.FromSeconds(5), Moo);
}
_schedule is injected via the constructor. The test I'm trying write is to make sure the task is scheduled when the handler starts. But I can't find a way to mock Schedule as it doesn't have a no-arg constructor and it doesn't implement an interface. I tried creating an actual instance of it with a mocked IBuilder but can't figure out what expectations to set on the IBuilder. Also, I looked at the source to see how they were testing Schedule but it looks like we're on an earlier version (v5.0.0 via nuget) because we don't have a DefaultScheduler which appears to be what they use in their current tests.
In fact NServiceBus team has already covered the scheduler with unit/acceptance test, i.e. there is no need to check whether the task was actually scheduled when your handler is executed. Instead you would probably want to unit test your handler itself, thus check if call to scheduler.Every() has been made. Here is simple example of how your unit test might look like:
[TestClass]
public class Tests
{
[TestMethod]
public void When_executing_handler_the_task_should_be_scheduled()
{
//arrange
var scheduler = new FakeSheduler();
//act
var handler = new TestHandler(scheduler);
handler.Start();
//assert
Assert.IsTrue(scheduler.WasCalled);
}
}
The handler itself:
class TestHandler: IWantToRunWhenBusStartsAndStops
{
readonly IMyScheduler _scheduler;
public TestHandler(IMyScheduler scheduler)
{
_scheduler = scheduler;
}
public void Start()
{
_scheduler.Every(TimeSpan.FromSeconds(5), () => { });
}
public void Stop() { }
}
Finally, you have to abstract from direct usage of NServiceBus scheduler in order to make it testable, here is the idea:
interface IMyScheduler
{
void Every(TimeSpan interval, Action action);
}
//your real implementation
class MySheduler: IMyScheduler
{
readonly Schedule _schedule;
public MySheduler(Schedule schedule)
{
_schedule = schedule;
}
public void Every(TimeSpan interval, Action action)
{
_schedule.Every(TimeSpan.FromSeconds(5), () => { });
}
}
//fake for the testing
class FakeSheduler: IMyScheduler
{
public bool WasCalled { get; set; }
public void Every(TimeSpan interval, Action action)
{
WasCalled = true;
}
}
Related
Following are the classes used to implement retry logic
TestRetry Class:
public class TestRetry implements IRetryAnalyzer {
int counter=0;
int retryLimit=2;
#Override
public boolean retry(ITestResult result) {
if (counter < retryLimit) {
TestReporter.logStep("Retrying Test " +result.getName()+" for number of times: "+(counter+1));
counter++;
return true;
}
return false;
}
RetryListener Class:
public class RetryListener implements IAnnotationTransformer {
#Override
public void transform(ITestAnnotation annotation, Class testClass, Constructor testConstructor, Method testMethod) {
// TODO Auto-generated method stub
IRetryAnalyzer retry = annotation.getRetryAnalyzer();
if (retry == null) {
annotation.setRetryAnalyzer(TestRetry.class);
}
}}
SampleTest:
#Listeners(RetryListener.class)
public class SampleTest {
#BeforeSuite(alwaysRun = true)
public void beforeSuite(ITestContext context) {
for (ITestNGMethod method : context.getAllTestMethods()) {
method.setRetryAnalyzer(new TestRetry());
}
}
#Test(priority=0)
public void firsttest() {
System.out.println();
TestReporter.assertEquals("Test", "Test", "pass");
}
#Test(priority=1, dependsOnMethods="firsttest")
public void secondtest() {
TestReporter.assertEquals("Test", "Test1", "fail");
}
#Test(priority=2,dependsOnMethods="secondtest")
public void thirdtest() {
TestReporter.assertEquals("Test", "Test", "pass");
}
}
When I execute the above test, following is the output
firsttest gets executed and passes
secondtest depends on firsttest and gets executed, its failed - Retried 3 times and failed again
thirdtest skipped because it depends on secondtest.
Output achieved as expected.
Question:
Since the tests are dependent. If one of the tests fails, I want to execute the whole class from first. is there a way to do it?
Examples:
If secondtest fails, I want to execute the whole class SampleTest again.
Thanks!
There's currently no way of achieving what you are asking for.
TestNG will only retry a failed test, but will not go up the execution ladder to find out all the upstream dependencies and try running them as well (Your ask is a very specific variant of this generic use case).
If you come to think of it, a dependent test is being executed only because its upstream dependencies (methods on which it depends on) have been executed successfully. So if there's a failure in the current test, why would one need to re-execute the already satisfied upstream dependencies? Its counter intuitive.
For what you have as a use-case, you should be merely building the entire logic within a #Test method, wherein you take care of handling the retries and also the invocation of the entire chain once again, if there were failures.
The below sample should clarify that
public class SampleTest {
#Test (retryAnalyzer = TestRetry.class)
public void orchestrateTest() {
firsttest();
secondtest();
thirdtest();
}
public void firsttest() {
System.out.println();
TestReporter.assertEquals("Test", "Test", "pass");
}
public void secondtest() {
TestReporter.assertEquals("Test", "Test1", "fail");
}
public void thirdtest() {
TestReporter.assertEquals("Test", "Test", "pass");
}
}
TestNG does not support the use case that you are looking for in your question.
On a side note, you cannot wire in a IAnnotationTransformer listener via an #Listeners annotation (this is explicitly called out in the javadocs of this interface). It can only be wired in via the <listeners> tag in your suite xml (or) by referring to it in the META-INF\services\org.testng.ITestNGListener file (its called the Service Provider Interface approach in Java)
I got a project built under ASP Core 2 that utilizes the Quartz.NET scheduler 3-beta1
I've got the following job that i want to execute:
public class TestJob: IJob
{
private readonly AppDbContext _dbContext;
public TestJob(AppDbContext dbContext)
{
_dbContext = dbContext;
}
public Task Execute(IJobExecutionContext context)
{
Debug.WriteLine("Test check at " + DateTime.Now);
var testRun = _dbContext.TestTable.Where(o => o.CheckNumber > 10).ToList();
Debug.WriteLine(testRun.Count);
return Task.CompletedTask;
}
}
Unfortunately it never works and there are not error logs to indicate an issue.
Yet when i remove everything and just leave the Debug.WriteLine it works as per below example.
public class TestJob: IJob
{
public Task Execute(IJobExecutionContext context)
{
Debug.WriteLine("Test check at " + DateTime.Now);
return Task.CompletedTask;
}
}
How can i get my job to execute the database call?
EDIT 1: Job Creation
var schedulerFactory = new StdSchedulerFactory(properties);
_scheduler = schedulerFactory.GetScheduler().Result;
_scheduler.Start().Wait();
var testJob = JobBuilder.Create<TestJob>()
.WithIdentity("TestJobIdentity")
.Build();
var testTrigger = TriggerBuilder.Create()
.WithIdentity("TestJobTrigger")
.StartNow()
.WithSimpleSchedule(x => x.WithIntervalInMinutes(1).RepeatForever())
.Build();
if (CheckIfJobRegistered(testJob.Key).Result == false)
_scheduler.ScheduleJob(testJob, testTrigger).Wait();
The main problem here is that Quartz can't create the job and swallows the exception.
The Documentation states:
When a trigger fires, the JobDetail (instance definition) it is associated to is loaded, and the job class it refers to is instantiated via the JobFactory configured on the Scheduler. The default JobFactory simply calls the default constructor of the job class using Activator.CreateInstance, then attempts to call setter properties on the class that match the names of keys within the JobDataMap. You may want to create your own implementation of JobFactory to accomplish things such as having your application’s IoC or DI container produce/initialize the job instance.
Quartz provides the IJobFactory to achieve that. And it works really good with Dependency Injection. A JobFactory can look like this:
public class JobFactory : IJobFactory
{
//TypeFactory is just the DI Container of your choice
protected readonly TypeFactory Factory;
public JobFactory(TypeFactory factory)
{
Factory = factory;
}
public IJob NewJob(TriggerFiredBundle bundle, IScheduler scheduler)
{
try
{
return Factory.Create(bundle.JobDetail.JobType) as IJob;
}
catch (Exception e)
{
//Log the error and return null
//every exception thrown will be swallowed by Quartz
return null;
}
}
public void ReturnJob(IJob job)
{
//Don't forget to implement this,
//or the memory will not released
Factory.Release(job);
}
}
Then just register your JobFactory with the scheduler and everything should work:
_scheduler.JobFactory = new JobFactory(/*container of choice*/);
Edit:
Additionally you can take a look to one of my previous answers.
Imagine the following class hierarchy:
interface IRules
{
void NotifyPickup(object pickedUp);
void NotifyDeath();
void NotifyDamage();
}
class CaptureTheFlag : IRules
{
public void NotifyPickup(Pickup pickedUp)
{
if(pickedUp is Flag)
GameOver();
}
public void NotifyDeath()
{
}
public void NotifyDamage()
{
}
}
class DeathMatch : IRules
{
public void NotifyPickup(Pickup pickedUp)
{
points++;
}
public void NotifyDeath()
{
lives--;
}
public void NotifyDamage()
{
}
}
class GameWorld
{
IRules gameMode;
public Main(IRules gameMode)
{
this.gameMode = gameMode;
}
object[] worldObjects;
public void GameLoop()
{
foreach(object obj in worldObjects)
{
// This call may have a bunch of sideeffects, like getting a pickup
// Or a player dying
// Or damage being taken
// Different game modes are interested in different events / statistics.
obj.Update();
// Stuff happens...
gameMode.NotifyDamage();
// Stuff happens...
gameMode.NotifyDeath();
}
}
}
So here I've got an interface which contains Notify* functions. These are callbacks. Different game modes are interested in different events of the game. It's not really possible to access the concrete objects creating these events because they're buried in the worldObjects array. Imagine we are adding new game modes to our game. The IRules interface will get hugely bloated, containing all the possible things a game mode may be interested in, and most calls will be stubbed! How can I prevent this?
Edit 2: Concrete example
Seems like your Process logic sends out a lot of events. If you would give these events a name, you could subscribe your observers to them.
Then it would even be possible to create a 'filtering' observer that can forward the events to any other observer (a decorator pattern):
struct Event {
enum e { A, B, /*...*/ };
e name;
};
class IEventListener {
public:
virtual void event( Event e ) = 0;
};
// an event dispatcher implementation:
using namespace std;
class EventDispatcher {
public:
typedef std::shared_ptr<IEventListener> IEventListenerPtr;
map<Event::e,vector<IEventListenerPtr>> listeners;
void event(Event e){
const vector<IEventListenerPtr> e_listeners=listeners[e.name].second;
//foreach(begin(e_listeners)
// ,end(e_listeners)
// ,bind(IEventListener::event,_1,e));
for(vector<IEventListenerPtr>::const_iterator it=e_listeners.begin()
; it!=e_listeners.end()
; ++it)
{
(*it)->event(e);
}
}
};
You program could look like this:
Main main;
EventEventDispatcher f1;
f1.listeners[Event::A].push_back(listener1);
main.listener=f1;
Note: code untested - grab the idea.
If you really want to decouple the sender from the sink, you put an event system in between. The example given here is very dedicated and lightweight, but do sure take a look at various existing implementations: Signals and Slots implemented in Qt and in Boost, the delegates from C#, ...
Apologizes if I missed something but why not use event? Basically let IController expose void Callback() method, then Main would be able subscribe any callback to own event:
class Main
{
private event EventHandler SomeEvent;
public Main(IController controller)
{
// use weak events to avoid memory leaks or
// implement IDisposable here and unsubscribe explicitly
this.SomeEvent += controller.Callback;
}
public void ProcessStuff()
{
// invoke event here
SomeEvent();
}
}
EDIT:
This is what I would do: extract each rule action into the separate interface so you just implement what you need in concrete classes, for instance CaptureTheFlag class does only PickupFlag action for now so does not need Damage/Death methods, so just mark by IPickupable and that's it. Then just check whether concrete instance supports concrete actions and proceed with execute.
interface IPickupable
{
void NotifyPickup(object pickedUp);
}
interface IDeathable
{
void NotifyDeath();
}
interface IDamagable
{
void NotifyDamage();
}
class CaptureTheFlag : IPickupable
{
public void NotifyPickup(Pickup pickedUp)
{
if (pickedUp is Flag)
GameOver();
}
}
class DeathMatch : IPickupable, IDeathable
{
public void NotifyPickup(Pickup pickedUp)
{
points++;
}
public void NotifyDeath()
{
lives--;
}
}
class GameWorld
{
public void GameLoop()
{
foreach(object obj in worldObjects)
{
obj.Update();
IPickupable pickupable = gameMode as IPickupable;
IDeathable deathable = gameMode as IDeathable;
IDamagable damagable = gameMode as IDamagable;
if (pickupable != null)
{
pickupable.NotifyPickup();
}
if (deathable != null)
{
deathable.NotifyDeath();
}
if (damagable != null)
{
damagable.NotifyDamage();
}
}
}
}
My final solution was the C# equivalent of what xtofl posted. I created a class which stored a bunch of delegates in it. These delegates started off with default values (so they would never be null) and the different concrete IRules classes could choose to overwrite them or not. This worked better than abstract or stubbed methods because it doesn't clog the interface with unrelated methods.
class GameEvents
{
public Action<Player> PlayerKilled = p => {};
public Func<Entity, bool> EntityValid = e => true;
public Action ItemPickedUp = () => {};
public Action FlagPickedUp = () => {};
}
class IRules
{
GameEvents Events { get; }
}
class CaptureTheFlag : IRules
{
GameEvents events = new GameEvents();
public GameEvents Events
{
get { return events; }
}
public CaptureTheFlag()
{
events.FlagPickedUp = FlagPickedUp;
}
public void FlagPickedUp()
{
score++;
}
}
Each rule set can choose which events it wants to listen to. The game simply calls then by doing Rules.Events.ItemPickedUp();. It's guaranteed never to be null.
Thanks to xtofl for the idea!
I want to write a TaskController for an ASP.NET MVC 3 application to some long running tasks, like sending a newsletter to the users of the site. I thought using an AsyncController would be appropriate as sending emails might take a while, and I want to be able to save some state to the database when the task finishes running.
Being the properly brought up developer that I am (:þ), and being really into BDD, I naturally want to start off with a spec using MSpec.
Imagine my controller looks like this:
public class TaskController : AsyncController
{
readonly ISession _session;
public TaskController(ISession session)
{
_session = session;
}
public void SendMailAsync()
{
// Get emails from db and send them
}
public ActionResult SendMailCompleted()
{
// Do some stuff here
}
}
How does one go about writing specs for AsyncControllers? Imagine I start with the following specification:
public class TaskControllerContext
{
protected static Mock<ISession> session;
protected static TaskController controller;
protected static ActionResult result;
}
[Subject(typeof(TaskController), "sending email")]
public class When_there_is_mail_to_be_sent : TaskControllerContext
{
Establish context = () =>
{
session = new Mock<ISession>();
controller = new TaskController(session.Object);
};
// is this the method to call?
Because of = () => controller.SendMailAsync();
// I know, I know, needs renaming...
It should_send_mail;
}
Should I be calling the SendMailAsync method for the test? I actually feels yucky.
How do I deal with the result from SendMailCompleted?
Well, I finally figured out at least a way to do it. I'm sure there are other and probably better ways, but here goes:
Declare an AutoResetEvent that will be used as wait handle and an EventHandler that will be set up to fire when the async action completes. Then in the Because block (corresponding to the Act part of unit testing) call WaitOne on the AutoResetEvent:
static AutoResetEvent waitHandle;
static EventHandler eventHandler;
static int msTimeout = 5000;
static IEnumerable<Email> response;
Establish context = () =>
{
toSend = new List<Email>
{
// Emails here
};
// Prepare the mock objects
session.Setup(x => x.All<Email>()).Returns(toSend.AsQueryable());
mailer.Setup(x => x.SendMail(Moq.It.IsAny<IEnumerable<Email>>()))
.Returns(toSend);
// Set up the wait handle
waitHandle = new AutoResetEvent(false);
eventHandler = (sender, e) => waitHandle.Set();
controller.AsyncManager.Finished += eventHandler;
};
Because of = () =>
{
controller.SendMailAsync();
if (!waitHandle.WaitOne(msTimeout, false)) {}
response = (IEnumerable<Email>) controller.AsyncManager
.Parameters["sentMails"];
};
It should_send_mail = () => response.Any().ShouldBeTrue();
This should work as well if you're writting unit tests with NUnit or any other test framework instead of MSpec.
I have a service proxy class that makes asyn call to service operation. I use a callback method to pass results back to my view model.
Doing functional testing of view model, I can mock service proxy to ensure methods are called on the proxy, but how can I ensure that callback method is called as well?
With RhinoMocks I can test that events are handled and event raise events on the mocked object, but how can I test callbacks?
ViewModel:
public class MyViewModel
{
public void GetDataAsync()
{
// Use DI framework to get the object
IMyServiceClient myServiceClient = IoC.Resolve<IMyServiceClient>();
myServiceClient.GetData(GetDataAsyncCallback);
}
private void GetDataAsyncCallback(Entity entity, ServiceError error)
{
// do something here...
}
}
ServiceProxy:
public class MyService : ClientBase<IMyService>, IMyServiceClient
{
// Constructor
public NertiAdminServiceClient(string endpointConfigurationName, string remoteAddress)
:
base(endpointConfigurationName, remoteAddress)
{
}
// IMyServiceClient member.
public void GetData(Action<Entity, ServiceError> callback)
{
Channel.BeginGetData(EndGetData, callback);
}
private void EndGetData(IAsyncResult result)
{
Action<Entity, ServiceError> callback =
result.AsyncState as Action<Entity, ServiceError>;
ServiceError error;
Entity results = Channel.EndGetData(out error, result);
if (callback != null)
callback(results, error);
}
}
Thanks
Played around with this a bit and I think I may have what you're looking for. First, I'll display the MSTest code I did to verify this:
[TestClass]
public class UnitTest3
{
private delegate void MakeCallbackDelegate(Action<Entity, ServiceError> callback);
[TestMethod]
public void CallbackIntoViewModel()
{
var service = MockRepository.GenerateStub<IMyServiceClient>();
var model = new MyViewModel(service);
service.Stub(s => s.GetData(null)).Do(
new MakeCallbackDelegate(c => model.GetDataCallback(new Entity(), new ServiceError())));
model.GetDataAsync(null);
}
}
public class MyViewModel
{
private readonly IMyServiceClient client;
public MyViewModel(IMyServiceClient client)
{
this.client = client;
}
public virtual void GetDataAsync(Action<Entity, ServiceError> callback)
{
this.client.GetData(callback);
}
internal void GetDataCallback(Entity entity, ServiceError serviceError)
{
}
}
public interface IMyServiceClient
{
void GetData(Action<Entity, ServiceError> callback);
}
public class Entity
{
}
public class ServiceError
{
}
You'll notice a few things:
I made your callback internal. You'll need to use the InternalsVisisbleTo() attribute so your ViewModel assembly exposes internals to your unit tests (I'm not crazy about this, but it happens in rare cases like this).
I use Rhino.Mocks "Do" to execute the callback whenever the GetData is called. It's not using the callback supplied, but this is really more of an integration test. I assume you've got a ViewModel unit test to make sure that the real callback passed in to GetData is executed at the appropriate time.
Obviously, you'll want to create mock/stub Entity and ServiceError objects instead of just new'ing up like I did.