Correct way to test a function












0















Is it okay to call build_admins_message in the tests to build expected result that will be used in mock assertion?



Implementation:



@slack_messages.on_pattern('(?i)^admins$')
def handle_admins_message(event, body, match):
team_id = event['team_id']
user_id = body['user']

message = build_admins_message(team_id, user_id)
Slack(team_id).send_message(user_id, **message)


Tests:



class TestAdminsMessageHandler(TestCase):
def setUp(self):
team = SlackTeam.objects.create(team_id='TEAMID')
SlackUser.objects.create(team=team, user_id='USERID')

def tearDown(self):
SlackUser.objects.all().delete()
SlackTeam.objects.all().delete()

@mock.patch('slango.slack.Slack.send_message')
def test_correct_text(self, send_message_mock):
event = {
'team_id': 'TEAMID',
'event': {
'text': 'admins',
'user': 'USERID'
}
}

handle_admins_message(event, event['event'])

expected_message = build_admins_message('TEAMID', 'USERID')

send_message_mock.assert_called_with('USERID', **expected_message)


Implementation of the build_admins_message:



def build_admins_message(team_id, user_id):
user = SlackUser.retrieve(team_id, user_id)
admins = SlackUser.objects.filter(
is_bot_admin=True, team__team_id=team_id).order_by(
'real_name', 'display_name')

attachments =
if user.is_bot_admin:
attachments.append(build_admin_picker())

for admin in admins:
attachments.append(build_admin_item(user, admin))

attachments.append(build_admin_more())

return {
'text': "Here is users with admin rights:",
'attachments': attachments
}









share|improve this question





























    0















    Is it okay to call build_admins_message in the tests to build expected result that will be used in mock assertion?



    Implementation:



    @slack_messages.on_pattern('(?i)^admins$')
    def handle_admins_message(event, body, match):
    team_id = event['team_id']
    user_id = body['user']

    message = build_admins_message(team_id, user_id)
    Slack(team_id).send_message(user_id, **message)


    Tests:



    class TestAdminsMessageHandler(TestCase):
    def setUp(self):
    team = SlackTeam.objects.create(team_id='TEAMID')
    SlackUser.objects.create(team=team, user_id='USERID')

    def tearDown(self):
    SlackUser.objects.all().delete()
    SlackTeam.objects.all().delete()

    @mock.patch('slango.slack.Slack.send_message')
    def test_correct_text(self, send_message_mock):
    event = {
    'team_id': 'TEAMID',
    'event': {
    'text': 'admins',
    'user': 'USERID'
    }
    }

    handle_admins_message(event, event['event'])

    expected_message = build_admins_message('TEAMID', 'USERID')

    send_message_mock.assert_called_with('USERID', **expected_message)


    Implementation of the build_admins_message:



    def build_admins_message(team_id, user_id):
    user = SlackUser.retrieve(team_id, user_id)
    admins = SlackUser.objects.filter(
    is_bot_admin=True, team__team_id=team_id).order_by(
    'real_name', 'display_name')

    attachments =
    if user.is_bot_admin:
    attachments.append(build_admin_picker())

    for admin in admins:
    attachments.append(build_admin_item(user, admin))

    attachments.append(build_admin_more())

    return {
    'text': "Here is users with admin rights:",
    'attachments': attachments
    }









    share|improve this question



























      0












      0








      0








      Is it okay to call build_admins_message in the tests to build expected result that will be used in mock assertion?



      Implementation:



      @slack_messages.on_pattern('(?i)^admins$')
      def handle_admins_message(event, body, match):
      team_id = event['team_id']
      user_id = body['user']

      message = build_admins_message(team_id, user_id)
      Slack(team_id).send_message(user_id, **message)


      Tests:



      class TestAdminsMessageHandler(TestCase):
      def setUp(self):
      team = SlackTeam.objects.create(team_id='TEAMID')
      SlackUser.objects.create(team=team, user_id='USERID')

      def tearDown(self):
      SlackUser.objects.all().delete()
      SlackTeam.objects.all().delete()

      @mock.patch('slango.slack.Slack.send_message')
      def test_correct_text(self, send_message_mock):
      event = {
      'team_id': 'TEAMID',
      'event': {
      'text': 'admins',
      'user': 'USERID'
      }
      }

      handle_admins_message(event, event['event'])

      expected_message = build_admins_message('TEAMID', 'USERID')

      send_message_mock.assert_called_with('USERID', **expected_message)


      Implementation of the build_admins_message:



      def build_admins_message(team_id, user_id):
      user = SlackUser.retrieve(team_id, user_id)
      admins = SlackUser.objects.filter(
      is_bot_admin=True, team__team_id=team_id).order_by(
      'real_name', 'display_name')

      attachments =
      if user.is_bot_admin:
      attachments.append(build_admin_picker())

      for admin in admins:
      attachments.append(build_admin_item(user, admin))

      attachments.append(build_admin_more())

      return {
      'text': "Here is users with admin rights:",
      'attachments': attachments
      }









      share|improve this question
















      Is it okay to call build_admins_message in the tests to build expected result that will be used in mock assertion?



      Implementation:



      @slack_messages.on_pattern('(?i)^admins$')
      def handle_admins_message(event, body, match):
      team_id = event['team_id']
      user_id = body['user']

      message = build_admins_message(team_id, user_id)
      Slack(team_id).send_message(user_id, **message)


      Tests:



      class TestAdminsMessageHandler(TestCase):
      def setUp(self):
      team = SlackTeam.objects.create(team_id='TEAMID')
      SlackUser.objects.create(team=team, user_id='USERID')

      def tearDown(self):
      SlackUser.objects.all().delete()
      SlackTeam.objects.all().delete()

      @mock.patch('slango.slack.Slack.send_message')
      def test_correct_text(self, send_message_mock):
      event = {
      'team_id': 'TEAMID',
      'event': {
      'text': 'admins',
      'user': 'USERID'
      }
      }

      handle_admins_message(event, event['event'])

      expected_message = build_admins_message('TEAMID', 'USERID')

      send_message_mock.assert_called_with('USERID', **expected_message)


      Implementation of the build_admins_message:



      def build_admins_message(team_id, user_id):
      user = SlackUser.retrieve(team_id, user_id)
      admins = SlackUser.objects.filter(
      is_bot_admin=True, team__team_id=team_id).order_by(
      'real_name', 'display_name')

      attachments =
      if user.is_bot_admin:
      attachments.append(build_admin_picker())

      for admin in admins:
      attachments.append(build_admin_item(user, admin))

      attachments.append(build_admin_more())

      return {
      'text': "Here is users with admin rights:",
      'attachments': attachments
      }






      python unit-testing testing mocking integration-testing






      share|improve this question















      share|improve this question













      share|improve this question




      share|improve this question








      edited Jan 2 at 14:08







      oneor0

















      asked Jan 2 at 13:09









      oneor0oneor0

      609618




      609618
























          1 Answer
          1






          active

          oldest

          votes


















          2














          This would depend on the role of build_admins_message in your program.



          Since different parts of the program all need to build the message in the same way, this is probably okay. Consider whether you can make it more explicit that build_admins_message is used like this, e.g. with dependency injection. Make sure your helper method has its own test. (I usually see using patch as a design smell, but remember that doesn't automatically mean something is wrong!)



          If instead build_admins_message existed solely as a helper function for handle_admins_message, then using it in your test violates encapsulation and ties your test to the implementation too much. In that case, I would just manually write out the expected message in my test.






          share|improve this answer


























          • I use build_admins_message function multiple times throughout my program and I would prefer to manually write out expected message too, but build_admins_message returns pretty big dictionary.

            – oneor0
            Jan 2 at 13:56











          • How can I make build_admins_message a more explicit dependency?

            – oneor0
            Jan 2 at 14:01











          • I've added implementation to the question

            – oneor0
            Jan 2 at 14:09













          • @DmitryChernyshov Looking at it more, I probably wouldn't bother. Maybe patching out build_admins_message as well and asserting that that's called. Maybe if I knew your program and the Slack library better I would have a better idea.

            – JETM
            Jan 2 at 14:31











          Your Answer






          StackExchange.ifUsing("editor", function () {
          StackExchange.using("externalEditor", function () {
          StackExchange.using("snippets", function () {
          StackExchange.snippets.init();
          });
          });
          }, "code-snippets");

          StackExchange.ready(function() {
          var channelOptions = {
          tags: "".split(" "),
          id: "1"
          };
          initTagRenderer("".split(" "), "".split(" "), channelOptions);

          StackExchange.using("externalEditor", function() {
          // Have to fire editor after snippets, if snippets enabled
          if (StackExchange.settings.snippets.snippetsEnabled) {
          StackExchange.using("snippets", function() {
          createEditor();
          });
          }
          else {
          createEditor();
          }
          });

          function createEditor() {
          StackExchange.prepareEditor({
          heartbeatType: 'answer',
          autoActivateHeartbeat: false,
          convertImagesToLinks: true,
          noModals: true,
          showLowRepImageUploadWarning: true,
          reputationToPostImages: 10,
          bindNavPrevention: true,
          postfix: "",
          imageUploader: {
          brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
          contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
          allowUrls: true
          },
          onDemand: true,
          discardSelector: ".discard-answer"
          ,immediatelyShowMarkdownHelp:true
          });


          }
          });














          draft saved

          draft discarded


















          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f54006976%2fcorrect-way-to-test-a-function%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown

























          1 Answer
          1






          active

          oldest

          votes








          1 Answer
          1






          active

          oldest

          votes









          active

          oldest

          votes






          active

          oldest

          votes









          2














          This would depend on the role of build_admins_message in your program.



          Since different parts of the program all need to build the message in the same way, this is probably okay. Consider whether you can make it more explicit that build_admins_message is used like this, e.g. with dependency injection. Make sure your helper method has its own test. (I usually see using patch as a design smell, but remember that doesn't automatically mean something is wrong!)



          If instead build_admins_message existed solely as a helper function for handle_admins_message, then using it in your test violates encapsulation and ties your test to the implementation too much. In that case, I would just manually write out the expected message in my test.






          share|improve this answer


























          • I use build_admins_message function multiple times throughout my program and I would prefer to manually write out expected message too, but build_admins_message returns pretty big dictionary.

            – oneor0
            Jan 2 at 13:56











          • How can I make build_admins_message a more explicit dependency?

            – oneor0
            Jan 2 at 14:01











          • I've added implementation to the question

            – oneor0
            Jan 2 at 14:09













          • @DmitryChernyshov Looking at it more, I probably wouldn't bother. Maybe patching out build_admins_message as well and asserting that that's called. Maybe if I knew your program and the Slack library better I would have a better idea.

            – JETM
            Jan 2 at 14:31
















          2














          This would depend on the role of build_admins_message in your program.



          Since different parts of the program all need to build the message in the same way, this is probably okay. Consider whether you can make it more explicit that build_admins_message is used like this, e.g. with dependency injection. Make sure your helper method has its own test. (I usually see using patch as a design smell, but remember that doesn't automatically mean something is wrong!)



          If instead build_admins_message existed solely as a helper function for handle_admins_message, then using it in your test violates encapsulation and ties your test to the implementation too much. In that case, I would just manually write out the expected message in my test.






          share|improve this answer


























          • I use build_admins_message function multiple times throughout my program and I would prefer to manually write out expected message too, but build_admins_message returns pretty big dictionary.

            – oneor0
            Jan 2 at 13:56











          • How can I make build_admins_message a more explicit dependency?

            – oneor0
            Jan 2 at 14:01











          • I've added implementation to the question

            – oneor0
            Jan 2 at 14:09













          • @DmitryChernyshov Looking at it more, I probably wouldn't bother. Maybe patching out build_admins_message as well and asserting that that's called. Maybe if I knew your program and the Slack library better I would have a better idea.

            – JETM
            Jan 2 at 14:31














          2












          2








          2







          This would depend on the role of build_admins_message in your program.



          Since different parts of the program all need to build the message in the same way, this is probably okay. Consider whether you can make it more explicit that build_admins_message is used like this, e.g. with dependency injection. Make sure your helper method has its own test. (I usually see using patch as a design smell, but remember that doesn't automatically mean something is wrong!)



          If instead build_admins_message existed solely as a helper function for handle_admins_message, then using it in your test violates encapsulation and ties your test to the implementation too much. In that case, I would just manually write out the expected message in my test.






          share|improve this answer















          This would depend on the role of build_admins_message in your program.



          Since different parts of the program all need to build the message in the same way, this is probably okay. Consider whether you can make it more explicit that build_admins_message is used like this, e.g. with dependency injection. Make sure your helper method has its own test. (I usually see using patch as a design smell, but remember that doesn't automatically mean something is wrong!)



          If instead build_admins_message existed solely as a helper function for handle_admins_message, then using it in your test violates encapsulation and ties your test to the implementation too much. In that case, I would just manually write out the expected message in my test.







          share|improve this answer














          share|improve this answer



          share|improve this answer








          edited Jan 2 at 14:01

























          answered Jan 2 at 13:33









          JETMJETM

          2,10241729




          2,10241729













          • I use build_admins_message function multiple times throughout my program and I would prefer to manually write out expected message too, but build_admins_message returns pretty big dictionary.

            – oneor0
            Jan 2 at 13:56











          • How can I make build_admins_message a more explicit dependency?

            – oneor0
            Jan 2 at 14:01











          • I've added implementation to the question

            – oneor0
            Jan 2 at 14:09













          • @DmitryChernyshov Looking at it more, I probably wouldn't bother. Maybe patching out build_admins_message as well and asserting that that's called. Maybe if I knew your program and the Slack library better I would have a better idea.

            – JETM
            Jan 2 at 14:31



















          • I use build_admins_message function multiple times throughout my program and I would prefer to manually write out expected message too, but build_admins_message returns pretty big dictionary.

            – oneor0
            Jan 2 at 13:56











          • How can I make build_admins_message a more explicit dependency?

            – oneor0
            Jan 2 at 14:01











          • I've added implementation to the question

            – oneor0
            Jan 2 at 14:09













          • @DmitryChernyshov Looking at it more, I probably wouldn't bother. Maybe patching out build_admins_message as well and asserting that that's called. Maybe if I knew your program and the Slack library better I would have a better idea.

            – JETM
            Jan 2 at 14:31

















          I use build_admins_message function multiple times throughout my program and I would prefer to manually write out expected message too, but build_admins_message returns pretty big dictionary.

          – oneor0
          Jan 2 at 13:56





          I use build_admins_message function multiple times throughout my program and I would prefer to manually write out expected message too, but build_admins_message returns pretty big dictionary.

          – oneor0
          Jan 2 at 13:56













          How can I make build_admins_message a more explicit dependency?

          – oneor0
          Jan 2 at 14:01





          How can I make build_admins_message a more explicit dependency?

          – oneor0
          Jan 2 at 14:01













          I've added implementation to the question

          – oneor0
          Jan 2 at 14:09







          I've added implementation to the question

          – oneor0
          Jan 2 at 14:09















          @DmitryChernyshov Looking at it more, I probably wouldn't bother. Maybe patching out build_admins_message as well and asserting that that's called. Maybe if I knew your program and the Slack library better I would have a better idea.

          – JETM
          Jan 2 at 14:31





          @DmitryChernyshov Looking at it more, I probably wouldn't bother. Maybe patching out build_admins_message as well and asserting that that's called. Maybe if I knew your program and the Slack library better I would have a better idea.

          – JETM
          Jan 2 at 14:31




















          draft saved

          draft discarded




















































          Thanks for contributing an answer to Stack Overflow!


          • Please be sure to answer the question. Provide details and share your research!

          But avoid



          • Asking for help, clarification, or responding to other answers.

          • Making statements based on opinion; back them up with references or personal experience.


          To learn more, see our tips on writing great answers.




          draft saved


          draft discarded














          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f54006976%2fcorrect-way-to-test-a-function%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown





















































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown

































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown







          Popular posts from this blog

          MongoDB - Not Authorized To Execute Command

          How to fix TextFormField cause rebuild widget in Flutter

          in spring boot 2.1 many test slices are not allowed anymore due to multiple @BootstrapWith