如果你正在寻找实际的答案,这里是我的想法之一。
假设您想获取客户帐户,然后根据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 –