0

I have a method that I need to test. I would like to do so from the console. Here is the method, as well as some metadata from the class:

Include HS.Common

Class Custom.class Extends Ens.BusinessOperation
{
    Parameter ADAPTER = "EnsLib.EMail.OutboundAdapter";

    Property Adapter As EnsLib.EMail.OutboundAdapter;

    Method SendMessage(pSubject As %String, pMessage As %String, pEmailAddresses) As %Status
    {
        set tSC=$$$OK
        set tMailMessage=##class(%Net.MailMessage).%New()
        do tMailMessage.To.Insert($PIECE(pEmailAddresses,",",1))
        for tI=2:1:$LENGTH(pEmailAddresses,",") {
            do tMailMessage.Cc.Insert($PIECE(pEmailAddresses,",",tI))
        }

        set tMailMessage.Subject=pSubject
        set tMailMessage.Charset="iso-8859-1"
        set tSC=tMailMessage.TextData.Write(pMessage)
        quit:'tSC
        Set tSC1=..Adapter.SendMail(tMailMessage)
        if 'tSC1 {
            //Log warning about being unable to send mail.
            do $SYSTEM.Status.DecomposeStatus(tSC1,.err)
            $$$LOGWARNING("Could not send email: "_err(err))
            kill err
        }

        quit tSC
    }

    ...other methods here...

}

but when I perform this command:

set tResult = ##class(Custom.class).SendMessage("Test Subject","Test Message","my@email.com")

I get this error:

 Set tSC1=..Adapter.SendMail(tMailMessage)
 ^
<NO CURRENT OBJECT>zSendMessage+11^Custom.class.1

I tried instantiating adapter, much like the property definition, before calling the method but that did not work. How can I call this method from a console session?

1 Answers1

2

this method is an instance method, and you can't call it directly just for some class. Before, you should create an object, and then for that object, you can call any instance methods. But you still trying to call Ensemble classes, it is not so easy, because you should prepare environment, such as configured and started Ensemble Production, your class should be added as an Operation, configured and activated.

set oper=##class(Custom.class).%New("configName")

where configName - name for that operation in your production, by default it is same as class name (e.g. "Custom.class"). And now you can call your method.

write oper.SendMessage("testSubj","test body","my@mail.com")

But I would not recommend such way. It would be better if you test it through production, just sent test messages to this operation.

DAiMor
  • 3,185
  • 16
  • 24
  • Why do you recommend against doing it this way? –  Jan 12 '16 at 14:32
  • Because production and all of their parts is not suitable for calling from terminal. – DAiMor Jan 12 '16 at 15:18
  • I was able to do it using your method above (the config name is the piece I was missing) and it worked great. Is there potential for adverse consequences or is it just "not recommended"? –  Jan 12 '16 at 15:19
  • Potentially could be everything, and you should restart production every time when you change parameters in it in anyway. – DAiMor Jan 12 '16 at 15:21
  • To expand on @DAiMor 's comment, Ensemble is intended to keep the code *very* modular, independent and message-driven, so the right way to test something is to send in a message. The best way to manage that is to start a running production that you then test via message so that you most closely replicate the way the component will be called in your actual environment. It also means your test configuration can be exactly the same as your final configuration, the only difference may be the content of the messages that you send. – DdP Jan 29 '16 at 17:27