我有这种设置,我正在测试一个使用另一个类的类,我想模仿后者,所以我只测试第一个类本身。
nuclear_reactor.py
:
class NuclearReactor():
def __init__(self):
print "initializing the nuclear reactor"
def start(self):
print "starting the nuclear reactor"
nuclear_manager.py
:
from nuclear_reactor import NuclearReactor
class NuclearManager():
def __init__(self):
print "manager creating the nuclear reactor"
self.reactor = NuclearReactor()
def start(self):
print "manager starting the nuclear reactor"
self.reactor.start()
test_nuclear_manager.py
:
from mock import Mock
import nuclear_manager
from nuclear_manager import NuclearManager
def test():
mock_reactor = nuclear_manager.NuclearReactor = Mock()
nuke = NuclearManager()
nuke.start()
nuke.start()
print mock_reactor.mock_calls
print mock_reactor.start.call_count
test()
我想测试的是NuclearReactor.start
被调用,
但是当我跑步时,我得到了:
manager creating the nuclear reactor
manager starting the nuclear reactor
manager starting the nuclear reactor
[call(), call().start(), call().start()]
0
我完全理解,因为start
是实例的属性而不是类的属性,我可以解析mock_calls
,但是没有更好的方法来检查调用是一个实例化的模拟类?
我可以在NuclearManager
中使用依赖注入来传递模拟NuclearReactor
,但我认为只使用模拟会有另一种方法。
答案 0 :(得分:5)
您确实正在测试start
是否已直接在类上调用,而您的代码却没有。您可以直接在实例上测试该方法;请记住,通过调用类来生成实例:
print mock_reactor.return_value.calls
print mock_reactor.return_value.start.call_count
Mock.return_value
attribute是对模拟类的调用的结果,因此是实例。
你也可以调用模拟。默认情况下,Mocks在调用时总是返回完全相同的对象,一个表示该返回值的新模拟:
print mock_reactor().calls
print mock_reactor().start.call_count
调用模拟实例的结果和模拟实例return_value
属性是同一个。
通过打印出对NuclearReactor
模拟的调用,您已经走在正确的道路上了,您错过了在名为模拟器上调用start()
的详细信息,所以call().start()
,而非start()
已被记录。
您可能希望使用mock.patch()
来处理修补,而不是直接分配;这样可以确保再次删除补丁,以便其他测试可以自行决定被模拟的内容:
import mock
from nuclear_manager import NuclearManager
@mock.patch('nuclear_manager.NuclearReactor')
def test(mock_reactor):
nuke = NuclearManager()
nuke.start()
nuke.start()
instance = mock_reactor.return_value
assert instance.start.call_count == 2
instance.assert_called()
我在这里用作装饰器;当调用test()
函数时,模拟就会到位,当函数退出时,它会被再次删除。您还可以使用patch()
作为上下文管理器,以更加精细地限制补丁的范围。
此外,对于像这样的单元测试,请使用unittest
library:
import mock
import unittest
import nuclear_manager
class NuclearManagerTests(unittest.TestCase):
@mock.patch('nuclear_manager.NuclearReactor')
def test_start(self, mock_reactor):
nuke = NuclearManager()
nuke.start()
nuke.start()
instance = mock_reactor.return_value
self.assertEqual(instance.start.call_count, 2)
instance.assert_called()
if __name__ == '__main__':
unittest.main()
这使您可以将测试适合更大的测试套件,启用和禁用测试,以及与其他测试工具集成。
答案 1 :(得分:-2)
我使用模拟的方式是这样的:(代码是Python 3)
@NgModule({
providers: [
{ provide: HTTP_INTERCEPTORS, useClass: XxxInterceptor, multi: true },
],
})
export class XxxModule {
}
@NgModule({
declarations: [
],
imports: [
XxxModule,
HttpClientJsonpModule,
],
providers: [
...
],
bootstrap: [AppComponent]
})
export class AppModule { }
输出:
public string SendWebRequestSinProxy(string url)
{
//controlarTiempos("SendWebRequestSinProxy(string url)");
string result = "";
using (HttpClient client = new HttpClient())
{
client.DefaultRequestHeaders.TryAddWithoutValidation("Content-Type", "text/html; charset=utf-8");
client.Timeout.Add(new TimeSpan(1, 0, 0));
using (HttpResponseMessage response = client.GetAsync(url).Result)
{
using (HttpContent content = response.Content)
{
result = content.ReadAsStringAsync().Result;
}
}
}
return result;
}