locked
What is best way to handle this scenario? RRS feed

  • Question

  • Hello,

    Trying to provide  POST unit test code for Asp.NET Web API.

    Here is my brief POST code for REST API.

    public HTTPResponseMessage POST(object myData) {

          //..blahblah..my business logic

         MailMessage mailMessage = new MailMessage();

         mailMessage...

         SmtpClient mailClient = new SmtpClient();

         mailClient.Send(mailMessage);

        ....

        ...

       return Request.CreateResponse(currentStatusCode, myRespData);

    }

    [TestMethod]

    public void BlahBlahPostTest() {

                   MyController controller = new MyController();

                  HttpResponseMessage responseMessage = controller.Post(new myData());

                  Assert.AreEqual(blahblah..responseMessage...blahlblah);

    }

    Well..I don't want to send out actual email in this unit test...

    1. I could configure web.config to send out the mail message in my local folder instead of going out, and then check with them...well....not an option in my scenario.

    2. I could create an interface like.

        IBlahBlahMail {

            void Send(MailMessage mm);

        }

       then change the POST method like Post(object myData, IBlahBlahMail mail)...

       then use this interface to Send in the Post method..

       In my Test method, I could provide mock for this interface...

       However, not sure whether this method signature actually works in real web environment..

       I don't think it will...well..even though there is a way, I don't think this is a right option...

    Any idea?

    Thanks,

    Monday, April 28, 2014 2:09 PM

Answers

  • What?

    Didn't I say same thing in my original post?

    Yes, you can fake, mock, stub, fak2, fake3, ...whatever and then pass it....

    So you want to change the POST method signature to take extra parameter for your stub..and ..make test OK, and then fail in the real scenario?

    I don't think there is really *nice* way for this..only thing I can think of is that..maybe some flag can be defined in the configuration file...then check....like

    if(flagisdefinedinweb.config) {

       Smtp...

       blahblah..

       Send..

    }

    This is not an ideal way, but this is only way I can think of ..under REST web api context

    Or..wait...there could be another way...that...maybe use DI pattern..so..we can create a constructor that takes an interface for mailing from this api controller, then provide a fake stuff....in that way, we don't have to change the POST method signature..

    Anyway, thanks for your answer though.


    Thursday, May 1, 2014 2:11 PM

All replies

  • Hi T J,

    I am trying to involve someone familiar with this topic to further look at this issue. There might be some time delay. Appreciate your patience.

    Best Regard,


    We are trying to better understand customer views on social support experience, so your participation in this interview project would be greatly appreciated if you have time. Thanks for helping make community forums a great place.
    Click HERE to participate the survey.

    Wednesday, April 30, 2014 10:29 AM
  • Hi T J,

    You need to fake the SmtpClient type at run-time.

    You need to first add Fakes Assembly, then edit the System.fakes file under the Fakes folder, add:

    <ShimGeneration>
      <Add TypeName="SmtpClient"/>
    </ShimGeneration>
    

    Then have your unit test method to be similar to the following code which is quoted from this blog: http://blog.micic.ch/net/visual-studio-2012-fakes

    var stub = new Data.Fakes.StubIBankRepository();
     
        bool result = false;
        using (ShimsContext.Create())
        {
            // "Replace" the real SmtpClient.Send implementation.
            // (Full path: System.Net.Mail.Fakes.ShimSmtpClient)
            ShimSmtpClient.Constructor = self =>
            {
                var shim = new ShimSmtpClient(self);
                shim.SendStringStringStringString = (from, to, subject, body) => { };
            };
     
            /*** Act ***/
            var business = new Business.Bank(stub);
            result = business.Transfer(1, 2, 20000);
        }
     
        /*** Assert ***/
        Assert.IsTrue(result);
    

    You can also refer to this blog which has the detailed steps: https://timscyclingblog.wordpress.com/tag/unittest/

    Thanks.


    We are trying to better understand customer views on social support experience, so your participation in this interview project would be greatly appreciated if you have time. Thanks for helping make community forums a great place.
    Click HERE to participate the survey.

    Thursday, May 1, 2014 2:57 AM
  • What?

    Didn't I say same thing in my original post?

    Yes, you can fake, mock, stub, fak2, fake3, ...whatever and then pass it....

    So you want to change the POST method signature to take extra parameter for your stub..and ..make test OK, and then fail in the real scenario?

    I don't think there is really *nice* way for this..only thing I can think of is that..maybe some flag can be defined in the configuration file...then check....like

    if(flagisdefinedinweb.config) {

       Smtp...

       blahblah..

       Send..

    }

    This is not an ideal way, but this is only way I can think of ..under REST web api context

    Or..wait...there could be another way...that...maybe use DI pattern..so..we can create a constructor that takes an interface for mailing from this api controller, then provide a fake stuff....in that way, we don't have to change the POST method signature..

    Anyway, thanks for your answer though.


    Thursday, May 1, 2014 2:11 PM
  • Hi T J,

    The approach I posted above is the most common way, and your approach should also work. I'm marking your reply as answer, post here if you want further help.

    Thanks. 


    We are trying to better understand customer views on social support experience, so your participation in this interview project would be greatly appreciated if you have time. Thanks for helping make community forums a great place.
    Click HERE to participate the survey.

    Tuesday, May 6, 2014 1:35 AM