Can I patch an object method using a decorator - python-3.x

Challenge: Patching/mocking a method call in a remote class to return a known piece of data.
I have a whole series of tests that look like:
#pytest.mark.gen_test
def test_assignment5(app):
with patch.object(BaseHandler, 'get_current_user') as mock_user:
mock_user.return_value = {"name": '1_kiz'}
with patch.object(BaseHandler, 'get_auth_state') as mock_state:
mock_state.return_value = { "course_id": "course_2",
"course_role": "Instructor",
"course_title": "A title",
}
r = yield async_requests.get(app.url + "/assignment?course_id=course_2&assignment_id=assign_a")
assert r.status_code == 200
response_data = r.json()
assert response_data["success"] == False
assert response_data["note"] == "Assignment assign_a does not exist"
(app is the core method for my application, and get_current_user & get_auth_state use information outside the scope of the app to get a value, so need fudged)
..... the repeating with segments offend my sensibility of good-looking code.
I know I could pull the return-value dictionaries to top-level variables, and that would reduce some of the repeated code, however I'm still repeating the with patch.object stuff every time.
Reading https://docs.python.org/dev/library/unittest.mock.html#unittest.mock.patch I know I could simply decorate each test, however
user_kiz = { ... }
auth_inst = { ... }
....
#pytest.mark.gen_test
#patch('BaseHandler.get_current_user', return_value = user_kiz)
#patch('BaseHandler.get_auth_state', return_value = auth_inst)
def test_assignment5a(app, kiz):
r = yield async_requests.get(app.url + "/assignment?course_id=course_2&assignment_id=assign_a")
assert r.status_code == 200
response_data = r.json()
assert response_data["success"] == False
assert response_data["note"] == "Assignment assign_a does not exist"
just gives me a ModuleNotFoundError: No module named 'BaseHandler' error.
Is there a way to patch/mock a method call in a remote class, allowing me to set the current_user & auth_state dictionaries for each call?
(ultimately, I will also need to test for different users, and different auth_states)

To replace a call like this:
with patch.object(a, 'b', c):
with a decorator, you'd use:
#patch.object(a, 'b', c)
You had switched to the string form
#patch(..., ...)
The string form requires the full import path as the first argument

Related

No such property: expected for class: Script1343 (in groovy script);

I am trying to retrieve data from oracle db but getting No such property: expected for class: Script1343 (in groovy script); error
import java.util.Properties;
import java.io.InputStream;
import groovy.sql.Sql;
def url = 'jdbc:oracle:thin:#//localhost:1521/TEST'
def user = 'DB'
def password = 'DB'
def driver = 'oracle.jdbc.driver.OracleDriver'
def sql = Sql.newInstance('url', 'User', 'password','oracle.jdbc.driver.OracleDriver')
sql.withStatement {
stmt -> stmt.queryTimeout = 30
print "Request TimeOut"
}
def rowNum = 0
sql.eachRow("SELECT DISTINCT CST_START_DT_PF,CST_ITEM_NUM_PF FROM COST "){ row ->
def first = row[0]
def middle = row.CST_START_DT_PF
def one = row.CST_ITEM_NUM_PF
assert expected[rowNum] == "$CST_START_DT_PF, $CST_ITEM_NUM_PF"
}
There are several things wrong. The specific error you asked about is the result of the following:
assert expected[rowNum] == "$CST_START_DT_PF, $CST_ITEM_NUM_PF"
You are referencing a variable expected which doesn't exist.
You didn't ask about the things below but other problems you are going to run into...
Referencing $CST_START_DT_PF and $CST_ITEM_NUM_PF is going to be a problem because they also don't exist, at least not in a way that your code will work.
You also are probably going to get unexpected results related to the fact that you are never incrementing rowNum.

Why is the setname function running?

I am trying to create a multipurpose program using Python3.
I have tested def weather(): and it works to show weather data for a given zip code. The program is supposed to never end unless the user types STOP.
The setname(): function is only supposed to run if the user types 'name' and 'my' or 'set'. When I run the program it asks, "What would you like to be called" no matter what I type. I tried even just typing z, but it still somehow started up the setname(): function. Please forgive me as this is my first time asking on stack.
What is causing the setname(): function to activate?
def weather():
import requests
wgURL = "http://api.wunderground.com/api/0def10027afaebb7/forecast/q/f/place.json"
print('What place are you looking for?')
wgURL = wgURL.replace('place', input())
r = requests.get(wgURL)
data = r.json()
for day in data['forecast']['simpleforecast']['forecastday']:
print (day['date']['weekday'] + ":")
print ("Conditions: ", day['conditions'])
print ("High: ", day['high']['fahrenheit'] + "F", "Low: ", day['low']['fahrenheit'] + "F", '\n')
def setname():
print('What would you like to be called?')
username = input()
print('Okay, I will now call you ' + username)
username = 'Anthony'
print('Done')
run = True
while run == True:
request = input()
if request == 'hi' or 'hello':
print('Hello there ' + username)
if 'weather' in request:
weather()
if 'name' and 'my' or 'set' in request:
setname()
if request == 'STOP':
run = False
Here is a screenshot from IDLE
You misunderstand how in works. Since in binds more tightly than either and or or, it turns out that 'name' and 'my' or 'set' in request means ('name' and 'my') or ('set' in request). This always evaluates to true, since 'name' is truthy and 'my' is truthy (both are non-empty strings).
Do this instead:
if ('name' in request and 'my' in request) or ('set' in request):
setname()
You likewise have a problem with request == 'hi' or 'hello': this means (request == 'hi') or 'hello', which is always true, since 'hello' is truthy. What you probably want here is:
if request == 'hi' or request == 'hello':
Consult the operator precedence table if it strikes your fancy.

How to null out exceptions in an htmlChecker

While this is a project assignment for class I am trying to understand how to do a specific part of the project.
I need to go through an html file and check if all the opening statements are matched to closing statements. Further, they must be in the correct order and this must be checked using a stack I've implemented. As of right now I am working on extracting each tag from the file. The tough part seems to be the two exceptions that I am working on here. The and the . I need these tags to be removed so the program doesn't read them as an opening or closing statement.
class Stack(object):
def __init__(self):
self.items = []
def isEmpty(self):
return self.items = []
def push(self, item):
self.items.append(item)
def pop(self):
return self.items[-1]
def getTag(file):
EXCEPTIONS = ['br/', 'meta']
s = Stack()
balanced = True
i = 0
isCopying = False
currentTag = ''
isClosing = False
while i < len(file) and balanced:
if symbol == "<":
if i < (len(file) - 1) and file[i + 1] == "/":
i = i + 1
isClosing == True
isCopying == True
if symbol == ">":
if isClosing == True:
top = s.pop()
if not matches(top, symbol):
balanced = False
else:
**strong text**
s.push(currentTag)
currentTag = ''
isCopying == False
if isCopying == True:
currentTag += symbol
The code reads in the file and goes letter by letter to search for <string>. If it exists it pushes it on to the stack. The matches functions checks to see if the closing statement equals the opening statement. The exceptions list is the ones I have to check for that will screw up the placing of the strings on the stack. I am having a tough time trying to incorporate them into my code. Any ideas? Before I push on to the stack I should go through a filter system to see whether that statement is valid or not valid. A basic if statement should suffice.
If I read your requirements correctly, you're going about this very awkwardly. What you're really looking to do is tokenize your file, and so the first thing you should do is get all the tokens in your file, and then check to see if it is a valid ordering of tokens.
Tokenization means you parse through your file and find all valid tokens and put them in an ordered list. A valid token in your case is any string length that starts with a < and ends with a >. You can safely discard the rest of the information I think? It would be easiest if you had a Token class to contain your token types.
Once you have that ordered list of tokens it is much easier to determine if they are a 'correct ordering' using your stack:
is_correct_ordering algorithm:
For each element in the list
if the element is an open-token, put it on the stack
if the element is a close-token
if the stack is empty return false
if the top element of the stack is a matching close token
pop the top element of the stack
else return false
discard any other token
If the stack is NOT empty, return false
Else return true
Naturally, having a reasonable Token class structure makes things easy:
class Token:
def matches(t: Token) -> bool:
pass # TODO Implement
#classmethod
def tokenize(token_string: str) -> Token:
pass # TODO Implement to return the proper subclass instantiation of the given string
class OpenToken:
pass
class CloseToken:
pass
class OtherToken:
pass
This breaks the challenge into two parts: first parsing the file for all valid tokens (easy to validate because you can hand-compare your ordered list with what you see in the file) and then validating that the ordered list is correct. Note that here, too, you can simplify what you're working on by delegating work to a sub-routine:
def tokenize_file(file) -> list:
token_list = []
while i < len(file):
token_string, token_end = get_token(file[i:])
token_list.append = Token.tokenize(token_string)
i = i + token_end # Skip to the end of this token
return token_list
def get_token(file) -> tuple:
# Note this is a naive implementation. Consider the edge case:
# <img src="Valid string with >">
token_string = ""
for x in range(len(file)):
token_string.append(file[x])
if file[x] == '>':
return token_string, x
# Note that this function will fail if the file terminates before you find a closing tag!
The above should turn something like this:
<html>Blah<meta src="lala"/><body><br/></body></html>
Into:
[OpenToken('<html>'),
OtherToken('<meta src="lala"/>'),
OpenToken('<body>'),
OtherToken('<br/>'),
CloseToken('</body>'),
CloseToken('</html>')]
Which can be much more easily handled to determine correctness.
Obviously this isn't a complete implementation of your problem, but hopefully it will help straighten out the awkwardness you've chosen with your current direction.

Determining an end node from file parsed with XmlParser

I have a method which needs to search an xml file which was parsed using XmlParser for an element by name and return it only if that element is an end node. For example:
class xmlTest extends GroovyTestCase {
def void test(){
def xmlBody = """
<rootElement>
<elementWithOneChild>
<endElement>Here is the end</endElement>
</elementWithOneChild>
<elementWithManyChildren>
<one>1</one>
<two>1</two>
<three>1</three>
</elementWithManyChildren>
</rootElement>"""
def parsedBody = new XmlParser().parseText(xmlBody)
def search1 = parsedBody.depthFirst().grep({it.name() == "elementWithOneChild"})
println search1[0].children().size()
def search2 = parsedBody.depthFirst().grep({it.name() == "endElement"})
println search2[0].children().size()
def search3 = parsedBody.depthFirst().grep({it.name() == "elementWithManyChildren"})
println search3[0].children().size()
}
}
My attempt to use Node.children().size() works except for the 1 to 1 case where an element contains one child element. In this case, search1.children().size() and search2.children().size() both return 1. Although, the size for elementWithManyChildren is 3. I am looking for some way to be able to tell an end node apart from an element with one child.
One way I have found to work is:
try{
search1[0].children().iterator().next().name()
}catch(e){
//If the next node does not have a name, it is an end node
}
But that solution just seems like a poor one.
might waste a couple of cycles but this should allow you to find terminal nodes
assert search1[0].'**'.size() == 2
assert search2[0].'**'.size() == 1
assert search3[0].'**'.size() == 4

Sorting arrays in Groovy

I'm trying to compare two arrays in groovy. My attempts so far have yielded a mixed response and therefore I'm turning to the collective for advice.
In the following code I'm taking 2 REST responses, parsing them and placing everything under the Invoice node into an array. I then further qualify my array so I have a list of InvoiceIDs and then try to compare the results of the two responses to ensure they are the same.
When I compare the array of InvoiceIDs (Guids) they match - this is not what I expect as the invoice order is currently different between my my 2 response sources.
When I sort the arrays of Invoices IDs the results differ.
I'm suspecting my code is faulty, but have spent an hour rattling through it, to no avail.
Any advice on sorting arrays in groovy or on the code below would be most appreciated:
gu = new com.eviware.soapui.support.GroovyUtils( context )
def xmlSlurper = new groovy.util.XmlSlurper()
// Setting up the response parameters
def responseSTAGE = xmlSlurper.parseText(context.expand('${GET Invoices - STAGE#Response}'));
def responseSTAGE2 = xmlSlurper.parseText(context.expand('${GET Invoices - STAGE2#Response}'));
responseInvoicesSTAGE = responseSTAGE.Invoices
responseInvoicesSTAGE2 = responseSTAGE2.Invoices
def arrayOfInvoicesSTAGE = []
def arrayOfInvoicesSTAGE2 = []
def counter = 0
for (invoice in responseInvoicesSTAGE.Invoice) {
arrayOfInvoicesSTAGE[counter] = responseInvoicesSTAGE.Invoice[counter].InvoiceID
//log.info counter+" STAGE"+arrayOfInvoicesSTAGE[counter]
arrayOfInvoicesSTAGE2[counter] = responseInvoicesSTAGE2.Invoice[counter].InvoiceID
//log.info counter+" STAGE2"+arrayOfInvoicesSTAGE2[counter]
counter++
}
log.info arrayOfInvoicesSTAGE
log.info arrayOfInvoicesSTAGE2
def sortedSTAGE = arrayOfInvoicesSTAGE.sort()
def sortedSTAGE2 = arrayOfInvoicesSTAGE2.sort()
log.info sortedSTAGE
As an aside, can't you replace:
def arrayOfInvoicesSTAGE = []
def arrayOfInvoicesSTAGE2 = []
def counter = 0
for (invoice in responseInvoicesSTAGE.Invoice) {
arrayOfInvoicesSTAGE[counter] = responseInvoicesSTAGE.Invoice[counter].InvoiceID
//log.info counter+" STAGE"+arrayOfInvoicesSTAGE[counter]
arrayOfInvoicesSTAGE2[counter] = responseInvoicesSTAGE2.Invoice[counter].InvoiceID
//log.info counter+" STAGE2"+arrayOfInvoicesSTAGE2[counter]
counter++
}
with
def arrayOfInvoicesSTAGE = responseInvoicesSTAGE.Invoice*.InvoiceID
def arrayOfInvoicesSTAGE2 = responseInvoicesSTAGE2.Invoice*.InvoiceID
Two arrays are considered equal in Groovy if they have they have the same number of elements and each element in the same position are equal. You can verify this by running the following code in the Groovy console
Integer[] foo = [1,2,3,4]
Integer[] bar = [4,3,2,1]
assert foo != bar
bar.sort()
assert foo == bar

Resources