web
You’re offline. This is a read only version of the page.
close
Skip to main content
Community site session details

Community site session details

Session Id :
Dynamics 365 Community / Blogs / Jesús Almaraz blog / Test mock object with manua...

Test mock object with manual event subscription.

Jalmaraz Profile Picture Jalmaraz 669

What is manual subscription? If you set in a Codeunit the EventSubscriberInstance property this way, the Codeunit subscriptions will not be active, and will not do anything when triggering event is raised:
codeunit 50112 "Introduce Amount Error"
{
    EventSubscriberInstance = Manual;
If we want to active its subscriptions, we must follow the next steps:
Declare an instance of the Codeunit:
    var
        IntroduceAmountError: Codeunit "Introduce Amount Error";
Active its subscriptions with this statement:
BindSubscription(IntroduceAmountError);
This cause the subscriptions of the Codeunit are active, but only in this declared instance. If we lose the scope of the instance the subscriptions are disabled again. You also can disable these subscriptions in explicit way with this statement:
UnbindSubscription(IntroduceAmountError);

Why manual subscription? Side effects.

We know events are the best (and shortly the only) way to change application behavior because this way we don´t modify the core code application. Well, events are great, but we have sometimes a little problem: side effects. Sometimes we subscribe to a trigger, but we are no aware of the context we don´t want to use this trigger. We must consider too many things:
  • Is the rec temporary?
  • Is the RunTrigger active?
  • Are in the event triggered in code place we think, or this is an unforeseen triggering?
In subscriptions we must check a lot of things and could forget a lot of more things too. This is where manual subscription could help us. Navision don´t use too much this option, but I think it has a high potential.

Mock object for CONSISTENT error.

I was playing the different ways to check the CONSISTENT error (error that Navision raise when we post an unbalanced invoice) and I learn two facts:
  • This problem is solved with post preview. We can post in preview mode and check where is the unbalanced G/L entry.
  • If you try to do it, you will notice that is really hard to cause an intended CONSISTENT error. This will be the goal of the code above: create a mock object to replicate CONSISTENT posting error for testing purpose.
The first challenge is not modifying core code for such purpose. It´s easy with subscriptions this way, I create a Codeunit with this function:
    [EventSubscriber(ObjectType::Codeunit, Codeunit::"Sales-Post", 'OnBeforePostCustomerEntry', '', true, true)]
    local procedure IntroduceIncorrectAmount(var GenJnlLine: Record "Gen. Journal Line")
    begin
        with GenJnlLine do begin
            Amount := Amount + 1000;
        end;
    end;
We subscribe to Codeunit 80 Sales Post and before posting general journal with customer entry, I add a little difference of 1000 units of whatever currency (no matter which), then the posting become unbalancing and cause CONSISTENT error.
Done, but I don´t want to leave this error to other developers. And I would like to keep this code for further uses too, so I don´t want to delete this Codeunit: then we must do this:
codeunit 50112 "Introduce Amount Error"
{
    EventSubscriberInstance = Manual;
Everybody could post invoices without error unless running this Codeunit:
codeunit 50113 "Consistent Catcher"
{
    trigger OnRun()
    begin
        BindSubscription(IntroduceAmountError);
 
        if Page.RunModal(0, SalesHeader) <> Action::LookupOK then
            exit;
        BindSubscription(SalesPostYesNo);
        GenJnlPostPreview.Preview(SalesPostYesNo, SalesHeader);
        UnbindSubscription(IntroduceAmountError);
    end;
    var
        IntroduceAmountError: Codeunit "Introduce Amount Error";
With BindSubscription we active event subscription in Codeunit Introduce Amount Error, and all the sales posting now will give us an consistent error, but only posting we do through this Codeunit Consistent Catcher, others users will not be bothered by this artificial error raising.
We are creating a Sales-Post mock object to test CONSISTENT error check. So, we can easily replicate behaviors that will be hard to replicate without this tools.

Mock object recap.

Create a new Codeunit Introduce Amount Error: this Codeunit is subscribed to Sales-Post when customer ledger entry is posted:
codeunit 50112 "Introduce Amount Error"
{
    EventSubscriberInstance = Manual;
    [EventSubscriber(ObjectType::Codeunit, Codeunit::"Sales-Post", 'OnBeforePostCustomerEntry', '', true, true)]
    local procedure IntroduceIncorrectAmount(var GenJnlLine: Record "Gen. Journal Line")
    begin
        with GenJnlLine do begin
            Amount := Amount + 1000;
        end;
    end;
}
Create a new Codeunit Consistent Catcher that will be used as mock object instead standard posting preview. This Codeunit follows the next steps:
Declare an instance of Introduce Amount Error Codeunit:
    var
        IntroduceAmountError: Codeunit "Introduce Amount Error";
Active instance subscriptions with BindSubscription statement:
codeunit 50113 "Consistent Catcher"
{
    trigger OnRun()
    begin
        BindSubscription(IntroduceAmountError);
Run a page to select a sales document to post.
Run post preview with selected document and this is the main focus: document will be post unbalanced due event subscription of IntroduceIncorrectAmount function.
        BindSubscription(SalesPostYesNo);
        GenJnlPostPreview.Preview(SalesPostYesNo, SalesHeader);
        UnbindSubscription(IntroduceAmountError);
When we run this Codeunit we get the unbalanced ledger entries.
Preview.png
Disable manual events in instance with UnbindSubscription statement. Every post after this that we will do will be right and balanced.
        UnbindSubscription(IntroduceAmountError);

Comments

*This post is locked for comments