如何使用promises模拟$ http响应并返回虚拟数据

时间:2015-07-05 18:01:17

标签: angularjs unit-testing mocking jasmine

我正在调用API服务,它返回工厂的承诺。

这是我工厂的一部分。

            <LinearLayout 

            android:layout_height="match_parent" android:paddingLeft="@dimen/activity_horizontal_margin"
            android:orientation="vertical"
            android:paddingRight="@dimen/activity_horizontal_margin"
            android:paddingTop="@dimen/activity_vertical_margin"
            android:paddingBottom="@dimen/activity_vertical_margin" tools:context=".MainActivity"
            android:weightSum="1">

            <EditText
                android:layout_width="match_parent"
                android:hint="Username"
                android:layout_height="wrap_content"
                android:id="@+id/userName"
                android:layout_alignParentTop="true"
                android:layout_alignParentStart="true" />

            <EditText
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:id="@+id/password"
                android:hint="Password"/>

            <CheckBox
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="Remember me"
                android:id="@+id/checkBox"
                android:checked="false"
                />
            <LinearLayout
                android:orientation="horizontal"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:gravity="center_horizontal">

                <Button
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:text="Login"
                    android:id="@+id/button"
                    android:onClick="login"/>

                <Button
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:text="Signup"
                    android:id="@+id/button3"
                    android:onClick="signUp"/>

            </LinearLayout>

            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="fill_parent"
                android:gravity="center">
            <ProgressBar
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:id="@+id/progressBar2"/>

            </LinearLayout>
        </LinearLayout>

这是从控制器调用的地方:

     factories.factory('OnBoardingFactory', ['$http',

        function ($http) {

          var dataFactory = {};

          dataFactory.get = function (url) {
            return $http.get('http://localhost/api/onboarding/' + url)
          };

          return dataFactory
        }

     ]);

这样可以很好地返回控制器中的数据。但是当我来测试时我遇到了困难。这是我的测试脚本:

OnBoardingFactory.get('login?username=test&password=password')
   .then(function(response){
      $scope.response = response.status;
   })

调用var scope, FakeOnBoardingFactory, controller, q, deferred; beforeEach(module('app.module')); beforeEach(function () { FakeOnBoardingFactory = { get: function () { deferred = q.defer(); // Place the fake return object here deferred.resolve({ response: {status: 200}}); return deferred.promise; } }; spyOn(FakeOnBoardingFactory, 'get').and.callThrough(); }); beforeEach(inject(function ($q, $rootScope, $controller, $injector ) { scope = $rootScope.$new(); q = $q; controller = $controller(OnBoardingCtrl, { $scope: scope, OnBoardingFactory: FakeOnBoardingFactory }) })); it('Should call the form and return 200', function () { // Execute form scope.loginCredentials({$valid: true}); scope.$apply(); // Ensure script is called (which passes fine) expect(FakeOnBoardingFactory.get).toHaveBeenCalled(); scope.$apply(); // BREAKS HERE expect(scope.status).toBe(200); }) 时,这很好。然而,我运行expect(FakeOnBoardingFactory.get).toHaveBeenCalled();,它打破了“预期未定义为200”。

这表明我的FakeOnBoardingFactory没有返回任何数据。但我似乎无法找到问题。

1 个答案:

答案 0 :(得分:0)

必须是支持导致此错误的多个主体断言的更改。 现在的解决方法是要么不使用expect,要在end函数回调中执行断言。  因此,而不是.expect(200)。

end(function(err,res) { res.status.should.equal(200) },

或者如果你确实使用了expect ..你需要确保指定一个正文以及一个状态..

it('should assert status only 1', function(done){ 
var app = express(); 
app.get('/user', function(req, res){
 res.send(201, { name: 'tobi' }); }); request(app) .get('/user')
 .expect('Content-Type', /json/)
 .expect('Content-Length', '20')
 .expect(201)
 .end(function(err, res){
 if (err) throw err; 
}); 
})