我有一种情况需要监视在另一个方法被调用之后被调用的方法。
这是正在测试的课程/方法:
@Injectable()
export class SomeService {
constructor(private customHttpClient: CustomHttpClient) {
}
updateSomethingCool(signerVO: SignerVO): Observable<SignerVO> {
// ...
return this.customHttpClient.withCustomOverrides(new CustomErrorHandlerHttpInterceptorOverride({ passthroughStatusCodes: [BAD_REQUEST, BAD_GATEWAY] }))
.put<SignerVO>(`/my/url/goes/here`, signerVO);
}
}
此类使用CustomHttpClient,如下所示:
@Injectable()
export class CustomHttpClient extends HttpClient {
private interceptors: HttpInterceptor[] | null = null;
constructor(private injector: Injector,
originalHandler: HttpHandler, private originalBackend: HttpBackend) {
super(originalHandler);
}
public withCustomOverrides(...overrides: CustomHttpInterceptorOverride[]): HttpClient {
// do very customizable things here
return new CustomDelegatingHttpClient(
new CustomHttpInterceptingHandler(this.originalBackend, this.interceptors, overrides));
}
}
export class CustomDelegatingHttpClient extends HttpClient {
constructor(private delegate: HttpHandler) {
super(delegate);
}
}
这是我在单元测试中尝试确实调用过put
方法的情况,因此,我需要监视put
方法:
describe(SomeService.name, () => {
let service: SomeService;
let customHttpClient: CustomHttpClient;
let emptySignerVO: SignerVO = new SignerVO();
beforeEach(() => {
customHttpClient= <CustomHttpClient>{};
customHttpClient.put = () => null;
customHttpClient.withCustomOverrides = () => null;
service = new SomeService(customHttpClient);
});
describe('updateSomethingCool', () => {
it('calls put', () => {
spyOn(customHttpClient, 'put').and.stub();
service.updateSomethingCool(emptySignerVO);
expect(customHttpClient.put).toHaveBeenCalled();
});
});
现在,当我运行此命令时,很明显我收到以下失败消息:
TypeError: Cannot read property 'put' of null
但是,我不完全知道如何在测试的put
部分中定义withCustomOverrides
或beforeEach
方法。
请注意,CustomHttpClient
只是围绕Angular HttpClient
的定制包装类,它允许一些更详细的功能。
谢谢您的帮助!
答案 0 :(得分:0)
我认为您应该注入httpClient;
beforeEach((http: HttpClient) => {
httpClient = http;
httpClient.put = () => null;
httpClient.withCustomOverrides = () => null;
service = new SomeService(log, httpClient);});
答案 1 :(得分:0)
您是否使用Angular依赖项注入将HttpClient
注入到CustomHttpClient
中?在测试依赖于HttpClient
的服务时,您可以使用HttpTestingController
,对于服务单元测试,它可能如下所示:
it(`should get a new data instance of type T`,
async(inject([TestDataService, HttpTestingController],
(service: TestDataService, backend: HttpTestingController) => {
// ... tests here
})
));
答案 2 :(得分:0)
好吧,最后我实际上并没有那么遥远。实际的测试代码很好。 import mysql.connector
from bs4 import BeautifulSoup
import requests
URL = "https://www.tripadvisor.com.au/Restaurants-g255068-c8-Brisbane_Brisbane_Region_Queensland.html"
def get_info(link):
mydb = mysql.connector.connect(
host="localhost",
user="root",
passwd = "123",
database="mydatabase"
)
mycursor = mydb.cursor()
mycursor.execute("DROP TABLE if exists webdata")
mycursor.execute("CREATE TABLE if not exists webdata (name VARCHAR(255), bubble VARCHAR(255), review VARCHAR(255))")
response = requests.get(link)
soup = BeautifulSoup(response.text,"lxml")
for items in soup.find_all(class_="shortSellDetails"):
name = items.find(class_="property_title").get_text(strip=True)
bubble = items.find(class_="ui_bubble_rating").get("alt")
review = items.find(class_="reviewCount").get_text(strip=True)
mycursor.execute("INSERT INTO webdata (name,bubble,review) VALUES (%s,%s,%s)",(name,bubble,review))
mydb.commit()
#I wish to use the follwing three lines within another function to do the same
mycursor.execute("SELECT * FROM webdata")
for item in mycursor.fetchall():
print(item)
if __name__ == '__main__':
get_info(URL)
方法需要更新如下:
beforeEach()
我基本上只需要将beforeEach(() => {
customHttpClient = <CustomHttpClient>{};
customHttpClient.put = () => null;
customHttpClient.withCustomOverrides = () => customHttpClient;
service = new SomeService(customHttpClient);
});
对象分配给customHttpClient
方法。
如果您查看实际调用中方法链接的流程,那实际上是有道理的。