-1

I have a Flask app where some page content comes from a global variable. I'm trying to set up some unit testing to assert the data, but I can't seem to get even a local variable to work:

TEST_STRING = foo

self.assertIn(b['TEST_STRING'], response.data)

fails with:

NameError: name 'b' is not defined

If I reference the plain variable:

self.assertIn(TEST_STRING, response.data)

I get the expected failure:

TypeError: a bytes-like object is required, not 'str'

The test succeeds if I hard-code the variable data into the test, but I'd rather not have to update the test if the variable changes. What am I missing here?

mrrg
  • 21
  • 1
  • 4
  • _What am I missing here?_ For starters, you're missing the part where you show us the code where `b` is defined. – John Gordon Aug 20 '17 at 06:09
  • @JohnGordon the `b` is right there in my first code block, the first character after the opening parentheses. It is not defined elsewhere as it is a [string literal](https://docs.python.org/3.3/reference/lexical_analysis.html#string-and-bytes-literals). I believe your down vote was in error. – mrrg Aug 21 '17 at 07:38
  • That's where b is _referenced_, but you never showed us where b is _defined_, i.e. `b = ` and/or `global b`. (And I didn't downvote; I just commented.) – John Gordon Aug 21 '17 at 17:11
  • I assumed you intended `b` as a dictionary name. But now I think perhaps you intended `b` to indicate _byte string notation_, as in `b'hello'`. I think notation only works for string literals; for variables, use `bytes(TEST_STRING)` instead. – John Gordon Aug 21 '17 at 17:19
  • @JohnGordon thanks for your responses, and I apologize for assuming it was your downvote and not being more clear. I'm quite new to this. Yes, the `b` is used to indicate a bytes prefix but I guess it's shorthand and not quite equal to `bytes` in some cases. Switching as you suggested works, thank you! I also had to specify my encoding type to avoid a TypeError. Here is the line that works, pulling from global config: `self.assertIn(bytes(app.config['TEST_STRING'], "utf-8"), response.data)`. Thanks again. – mrrg Aug 21 '17 at 18:10

1 Answers1

0

The problem was with the bytes literal prefix b:

Bytes literals are always prefixed with 'b' or 'B'; they produce an instance of the bytes type instead of the str type. They may only contain ASCII characters; bytes with a numeric value of 128 or greater must be expressed with escapes.

While it sounds like bytesprefix = bytes type, this does not seem to work if the data comes from a variable.

The solution was to change the b prefix to the bytes functionbytes, which states:

Bytes objects can also be created with literals, see String and Bytes literals.

So while they appear interchangeable, this is not always the case!

For my use case, I also had to specify my encoding type for the bytes function.

Here is the working syntax to my original post's example:

self.assertIn(bytes(TEST_STRING, "utf-8"), response.data)

Thanks goes to John Gordon who suggested switching to bytes in the comments, but never officially answered. So after a few days, I'll go ahead and close this out now.

mrrg
  • 21
  • 1
  • 4