如果你正在尋找實際的答案,這裏是我的想法之一。
假設您想獲取客戶帳戶,然後根據API的輸入對其進行修改。
所以寫入數據層或查詢會是這個樣子:
type CustomerAccount struct{
id string // this data type will differ depends on your database.
Name string
Address string
Age int
// and any other attribute. this is just for example.
}
func (ca *CustomerAccount)GetCustomerAccount (id int) (CustomerAccount,error) {
var ca CostumerAccount
// write your query using any databases.
// return an error if error happens when you do query to the database.
return ca,nil
}
func (ca *CustomerAccount)SaveCustomerAccount(ca CustomerAccount) error {
// find and update the data from given CustomerAccount
return nil
}
保存上面的代碼命名customer_account.go
。
現在讓我們說你想從業務邏輯中分離數據庫查詢,或者在這種情況下,你的DAL和BLL分離。你可以使用該接口。創建匹配巫婆上述這樣的模型查詢方法,它的接口類型:
type CustomerAccountInterface interface {
GetCustomerAccount (id int) (CustomerAccount,error)
SaveCustomerAccount(ca CustomerAccount) error
}
保存爲customer_account_interface.go
。
現在我們想寫一個業務邏輯,它將負責修改數據,我們將把CusomerAccountInterface
稱爲業務邏輯。因爲我們正在創建一個API,因此我們聞用於此處理程序:
func EditCustomerAccount(ca CustomerAccountInterface) http.Handler {
return http.HandleFunc(func(w http.ResponseWritter, r *http.Request){
// get all the input from user using *http.Request like id and other input.
// get our CustomerAccount Data to modify it
customerAccount,err := ca.GetAccountCustomer(id)
// modify customerAccount Accordingly from the input data, for example
customerAccount.Name = inputName // you can change what ever you want with the data here. In this case we change the name only for example purpose.
// save your customerAccount to your database
err := ca.SaveCustomerAccount(customerAccount)
// send the response 200 ok resonse if no error happens
w.WriteHeader(http.StatusOk)
resp := response{} // you can create your response struct in other places.
resp.Message = "success update data"
json.NewEncoder(w).Encode(resp)
})
}
從我們已經分離處理程序的上述方法是與數據訪問或查詢數據庫,以便我們可以創建一個單元中的業務邏輯測試在處理像這樣的商業邏輯:
創建CustomerAccountMock
的嘲笑從數據訪問結果查詢:
type CustomerAccountMock struct {
err error
Data CutstomerAccount
}
func (ca *CustomerAccountMock)GetCustomerAccount (id int) (CustomerAccount,error) {
return ca.Data,nil
}
func (ca *CustomerAccountMock)SaveCustomerAccount(ca CustomerAccount) error {
return ca.err
}
現在我們可以寫出測試是這樣的:
func TestEditCustomerAccount(t *testing.T){
testObjects := []struct{
CMock CutomerAccountMock
}{
{
CMock : CustomerAccountMock{
err : errors.New("Test error")
Data : CustomerAccount{} // return an empty data
},
},
}
for _, testObject := range testObjects {
actualResponse := createRequestToHandler(testObject.CMock)
// here you can check your response from calling your request testing to your handler.
}
}
以上只是爲了讓我的想法如何在單獨的數據層和業務邏輯層上實現。你可以參考我的完整source code here。該代碼引用另一個測試用例,如更新驅動程序數據,但它是相同的方法。
但是,這種方法有一些缺點,對我來說,就像在測試時寫上千篇文章一樣,你必須要有耐心!
所以來你的問題
是否有必要在DAL和BLL中轉到Web應用程序?
是的,它的確如此。將數據訪問與業務邏輯層分離非常重要,以便我們可以對其進行單元測試。
在上面的例子中,邏輯非常簡單,但想象一下如果你有一個複雜的邏輯來操作數據,而且你沒有單獨的DAL和BLL。當涉及到更改邏輯或查詢時,它將在未來和其他開發人員中受到傷害。
感覺害怕改變和沮喪,當出現問題時肯定是你想避免發生在你的職業生涯中。
看看是否有幫助:http://stackoverflow.com/q/42791536/5779732,http://stackoverflow.com/a/42500771/5779732,http://stackoverflow.com/a/41824700/5779732 –