2013-10-16 27 views
0

我目前正在研究一个移动应用程序,我决定使用JQuery Mobile来实现它。然而,由于它是一个官方应用程序,它需要我对它进行测试,并且我决定和我一起学习在学校处理的茉莉花。使用Jasmine,JQuery Mobile和异步AJAX请求的组合测试DOM

目前我有一个客户端和服务器端使用AJAX($.getJSON)请求进行通信。

当其中一个AJAX请求转发到它的callback方法时,它将调用Notification类来实现带有通知的div

我当时的问题是,它似乎总是当我使用下面的代码工作:

window.setTimeout(function() { 
    var expectedResult = "error"; 
    var result = $("#test .ui-content .contentContainer .notification").text(); 
    expect(result).toEqual(expectedResult); 
}, 4000); 

然而,几天后,我开始了新的模块,并编辑这些值它继续工作,因为它的旧 - 非现有的代码,这将是非常错误的。

所以我注意到这个单元测试从来没有真正的工作。

所以我开始寻找替代方法,发现runswaitsFor函数,但我似乎无法让它们工作。

所以这里是一个考验:

it('should display an error when trying to add a new contact', function() { 
    runs(function() { 
     var contact = new Contact(); 
     contact.addContact(); 
    }); 

    waitsFor(function() { 
     expect($("#test .ui-content .contentContainer .notification")).toBeVisible(); 
    }, 5000); 

    var expectedResult = "asdf"; 
    var result = $("#test .ui-content .contentContainer .notification").text(); 
    expect(result).toEqual(expectedResult); 
}); 

回调方法:

this.addContact_callback = function (data) { 
    $('#createContactForm')[0].reset(); 
    $('.ui-dialog').dialog('close'); 
    window.setTimeout(function() { 
     (new Contact()).retrieveContactList(); 
     (new NotificationBox()).show(data.message[0], data.message[1]); 
    }, 250) 
}; 

我的通知:

function NotificationBox() { 
    this.show = function (message, type) { 
     var activePage = $("body .ui-page-active").attr("id"); 
     var create = "<div class='notification " + type + "'>" + message + "</div>"; 
     $("#" + activePage + " .ui-content .contentContainer .notification").remove(); 
     $("#" + activePage + " .ui-content .contentContainer").prepend(
      $(create).hide().fadeIn('slow').delay(2500).fadeOut('slow', function() { 
       $(this).remove(); 
      }) 
     ); 
    }; 
} 

我希望有人能够给我提供一个解决方案这个主要问题。

此致 Larssy1

回答

1

您滥用waitsFor方法。如果您阅读official documentationwaitsFor需要返回一个指示等待时间是否结束的值。

什么你可能想要做的是以下几点:

waitsFor(function() { 
    return $("#test .ui-content .contentContainer .notification").is(":visible"); 
}, 5000); 

您还缺少测试的最后部分运行块。

runs(function() { 
    var expectedResult = "asdf"; 
    var result = $("#test .ui-content .contentContainer .notification").text(); 
    expect(result).toEqual(expectedResult); 
}); 
+0

这两种方法都在那里,检查第二个代码片段。由于我没有答案,我目前正在重构我的代码,它允许我不通过DOM检查,而是通过返回的值。 – larssy1

0

虽然它可能不被视为解决方案,但它确实创建了更好的可管理和可测试的代码。

在我给出的代码示例中,我将代码转发到外部回调方法,如我在使用addContact_callback时给出的代码。跟踪实际结果的唯一方法是确定notification元素类的文本。

说完这句话,很明显,如果你面对这个问题,你可能已经写了脏代码。

因此,我将我的代码更改为更好的东西,它使用内部回调方法。这意味着代码看起来像这样的事情:

function handleSomething() { 
    this.retrieveSomething(function (data) { 
     console.log(data); 
    }); 
} 

function retrieveSomething (callback) { 
    $.ajax({ 
     type: "GET", 
     url: "127.0.0.1/my.php", 
     success: function (data, status, xhr) { 
      return callback($.parseJSON(data); 
     } 
    }); 
} 

这可以确保我的代码是比较容易的方式来测试,因为我可以实现自定义的回调函数的单元测试。

还记得旧的单元测试?嗯,这又来自:

window.setTimeout(function() { 
    var expectedResult = "error"; 
    var result = $("#test .ui-content .contentContainer .notification").text(); 
    expect(result).toEqual(expectedResult); 
}, 4000); 

到:

var contact = new Contact(); 
contact.retrieveSomething(function (data) { 
    var expectedResult = (new Contact()).errorMessages[4]; 
    expect(data.message).toBe(expectedResult); 
}); 

Conslusion:确保你随时可以测试你的回报输出,而不是简单地将其移动到用户界面,然后试图测试的结果是否和你所期望的一样。