feat(unittest): add more test case for apis. (#291)

* Add go coverall test

* Add go coverall test

* Add code cover

* Add testcase for message

* Add test case for error and queue

* Add more test case

* Add more test case
diff --git a/.travis.yml b/.travis.yml
index 99f27b5..b34cf49 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -26,4 +26,4 @@
 script:
   - export LD_LIBRARY_PATH=/usr/local/lib
   - cd ${GOPATH}/src/github.com/apache/rocketmq-client-go
-  - go test ./core
+  - go test ./core -coverprofile=coverage.txt -covermode=atomic
diff --git a/core/api_test.go b/core/api_test.go
index d7e9bbb..df7cfc0 100644
--- a/core/api_test.go
+++ b/core/api_test.go
@@ -76,3 +76,44 @@
 		" MaxCacheMessageSize: 1024, MaxCacheMessageSizeInMB: 2048, ]"
 	assert.Equal(t, expect, pcConfig.String())
 }
+
+func TestPullConfig_String(t *testing.T) {
+	pConfig := PullConsumerConfig{}
+	pConfig.GroupID = "testGroup"
+	pConfig.NameServer = "localhost:9876"
+	pConfig.NameServerDomain = "domain1"
+	pConfig.InstanceName = "testProducer"
+	pConfig.LogC = &LogConfig{
+		Path:     "/rocketmq/log",
+		FileNum:  16,
+		FileSize: 1 << 20,
+		Level:    LogLevelDebug}
+
+	expect := "PushConsumerConfig=[GroupId: testGroup, NameServer: localhost:9876, NameServerDomain: domain1, InstanceName: testProducer, " +
+		"LogConfig: {Path:/rocketmq/log FileNum:16 FileSize:1048576 Level:Debug}, ]"
+	assert.Equal(t, expect, pConfig.String())
+}
+
+func TestSessionCredentials_String(t *testing.T) {
+	pConfig := SessionCredentials{}
+	pConfig.AccessKey = "AK"
+	pConfig.SecretKey = "SK"
+	pConfig.Channel = "Cloud"
+
+	expect := "[accessKey: AK, secretKey: SK, channel: Cloud]"
+	assert.Equal(t, expect, pConfig.String())
+}
+
+func TestSendResult_String(t *testing.T) {
+	pConfig := SendResult{}
+	pConfig.Status = SendOK
+	pConfig.MsgId = "MessageId"
+	pConfig.Offset = 100000
+
+	expect := "[status: SendOK, messageId: MessageId, offset: 100000]"
+	assert.Equal(t, expect, pConfig.String())
+
+	pConfig.Status = SendFlushDiskTimeout
+	expect = "[status: SendFlushDiskTimeout, messageId: MessageId, offset: 100000]"
+	assert.Equal(t, expect, pConfig.String())
+}
diff --git a/core/error_test.go b/core/error_test.go
new file mode 100644
index 0000000..a729aad
--- /dev/null
+++ b/core/error_test.go
@@ -0,0 +1,56 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+package rocketmq
+
+import (
+	"github.com/stretchr/testify/assert"
+	"testing"
+)
+
+func TestRMQError_OK(t *testing.T) {
+	err := rmqError(0)
+	assert.Equal(t, NIL, err)
+}
+func TestRMQError_Failed(t *testing.T) {
+	err := rmqError(int(ErrNullPoint))
+	assert.Equal(t, ErrNullPoint, err)
+}
+func TestRMQError_String(t *testing.T) {
+	err := rmqError(1)
+	expect := "null point"
+	assert.Equal(t, expect, err.Error())
+}
+
+func TestRMQError_Unknown(t *testing.T) {
+	err := rmqError(-1000)
+	expect := "unknow error: -1000"
+	assert.Equal(t, expect, err.Error())
+}
+
+func TestRMQError_ErrorCode(t *testing.T) {
+	assert.Equal(t, "malloc memory failed", rmqError(int(ErrMallocFailed)).Error())
+	assert.Equal(t, "start producer failed", rmqError(int(ErrProducerStartFailed)).Error())
+	assert.Equal(t, "send message with sync failed", rmqError(int(ErrSendSyncFailed)).Error())
+	assert.Equal(t, "send message with orderly failed", rmqError(int(ErrSendOrderlyFailed)).Error())
+	assert.Equal(t, "send message with oneway failed", rmqError(int(ErrSendOnewayFailed)).Error())
+	assert.Equal(t, "send transaction message failed", rmqError(int(ErrSendTransactionFailed)).Error())
+	assert.Equal(t, "start push-consumer failed", rmqError(int(ErrPushConsumerStartFailed)).Error())
+	assert.Equal(t, "start pull-consumer failed", rmqError(int(ErrPullConsumerStartFailed)).Error())
+	assert.Equal(t, "fetch MessageQueue failed", rmqError(int(ErrFetchMQFailed)).Error())
+	assert.Equal(t, "fetch Message failed", rmqError(int(ErrFetchMessageFailed)).Error())
+	assert.Equal(t, "this function is not support", rmqError(int(ErrNotSupportNow)).Error())
+}
diff --git a/core/log_test.go b/core/log_test.go
index e2246f0..86cf4c5 100644
--- a/core/log_test.go
+++ b/core/log_test.go
@@ -36,3 +36,7 @@
 	assert.Equal(t, "{Path:/log/path1 FileNum:3 FileSize:1048576 Level:Trace}", logc.String())
 	logc.Level = LogLevelError
 }
+func TestLogLevel_String(t *testing.T) {
+	logc := LogConfig{Path: "/log/path1", FileNum: 3, FileSize: 1 << 20, Level: LogLevelDebug}
+	assert.Equal(t, "Debug", logc.Level.String())
+}
diff --git a/core/message_test.go b/core/message_test.go
index 1df6ade..28feb87 100644
--- a/core/message_test.go
+++ b/core/message_test.go
@@ -33,6 +33,22 @@
 	assert.Equal(t, expect, msg.String())
 }
 
+func TestMessage_GetProperty(t *testing.T) {
+	msg := Message{
+		Topic:          "testTopic",
+		Tags:           "TagA, TagB",
+		Keys:           "Key1, Key2",
+		Body:           "Body1234567890",
+		DelayTimeLevel: 8}
+	cmsg := goMsgToC(&msg)
+	newMsg := cMsgToGo(cmsg)
+	expect := "[Topic: testTopic, Tags: TagA, TagB, Keys: Key1, Key2, Body: Body1234567890, DelayTimeLevel: 8," +
+		" Property: map[]]"
+	assert.Equal(t, expect, newMsg.String())
+	val := newMsg.GetProperty("KEY")
+	assert.Empty(t,val)
+}
+
 func TestMessageExt_String(t *testing.T) {
 	msg := Message{
 		Topic:          "testTopic",
diff --git a/core/producer_test.go b/core/producer_test.go
index 04c007b..9519c63 100644
--- a/core/producer_test.go
+++ b/core/producer_test.go
@@ -16,28 +16,60 @@
  */
 package rocketmq
 
-//func TestCreateMessage(test *testing.T){
-//    fmt.Println("-----TestCreateMessage Start----")
-//    rocketmq.CreateMessage("testTopic")
-//    fmt.Println("-----TestCreateMessage Finish----")
-//}
-//
-//func TestDestroyMessage(test *testing.T){
-//    fmt.Println("-----TestCreateMessage Start----")
-//    msg := rocketmq.CreateMessage("testTopic")
-//    rocketmq.DestroyMessage(msg)
-//    fmt.Println("-----TestCreateMessage Finish----")
-//}
-//func TestSetMessageKeys(test *testing.T){
-//    fmt.Println("-----TestSetMessageKeys Start----")
-//    msg := rocketmq.CreateMessage("testTopic")
-//    len := rocketmq.SetMessageKeys(msg,"testKey")
-//    fmt.Println("Len:",len)
-//    rocketmq.DestroyMessage(msg)
-//    fmt.Println("-----TestCreateMessage Finish----")
-//}
-//func TestCreateProducer(test *testing.T){
-//    fmt.Println("-----TestCreateProducer Start----")
-//    rocketmq.CreateProducer("testGroupId")
-//    fmt.Println("-----TestCreateProducer Finish----")
-//}
+import (
+	"errors"
+	"github.com/stretchr/testify/assert"
+	"testing"
+)
+
+func TestProducer_SendStatus(t *testing.T) {
+	assert.Equal(t, "SendOK", SendStatus(int(SendOK)).String())
+	assert.Equal(t, "SendFlushDiskTimeout", SendStatus(int(SendFlushDiskTimeout)).String())
+	assert.Equal(t, "SendFlushSlaveTimeout", SendStatus(int(SendFlushSlaveTimeout)).String())
+	assert.Equal(t, "SendSlaveNotAvailable", SendStatus(int(SendSlaveNotAvailable)).String())
+	assert.Equal(t, "Unknown", SendStatus(int(-1)).String())
+}
+
+func TestProducer_CreateProducerFailed(t *testing.T) {
+	pConfig := ProducerConfig{}
+
+	producer, err := newDefaultProducer(nil)
+	assert.Nil(t, producer)
+	assert.Equal(t, err, errors.New("config is nil"))
+	producer, err = newDefaultProducer(&pConfig)
+	assert.Nil(t, producer)
+	assert.Equal(t, err, errors.New("GroupId is empty"))
+	pConfig.GroupID = "testGroup"
+	producer, err = newDefaultProducer(&pConfig)
+	assert.Nil(t, producer)
+	assert.Equal(t, err, errors.New("NameServer and NameServerDomain is empty"))
+	pConfig.NameServer = "localhost:9876"
+	pConfig.ProducerModel = TransProducer
+	producer, err = newDefaultProducer(&pConfig)
+	assert.Nil(t, producer)
+	assert.Equal(t, err, errors.New("ProducerModel is invalid or empty"))
+}
+
+func TestProducer_CreateProducer(t *testing.T) {
+	pConfig := ProducerConfig{}
+	pConfig.GroupID = "testGroup"
+	pConfig.NameServer = "localhost:9876"
+	pConfig.InstanceName = "testProducer"
+	pConfig.Credentials = &SessionCredentials{
+		AccessKey: "AK",
+		SecretKey: "SK",
+		Channel:   "Cloud"}
+	pConfig.LogC = &LogConfig{
+		Path:     "/rocketmq/log",
+		FileNum:  16,
+		FileSize: 1 << 20,
+		Level:    LogLevelDebug}
+	pConfig.SendMsgTimeout = 30
+	pConfig.CompressLevel = 4
+	pConfig.MaxMessageSize = 1024
+	pConfig.ProducerModel = CommonProducer
+
+	producer, err := newDefaultProducer(&pConfig)
+	assert.Nil(t, err)
+	assert.NotEmpty(t, producer)
+}
diff --git a/core/pull_consumer_test.go b/core/pull_consumer_test.go
new file mode 100644
index 0000000..528dc9c
--- /dev/null
+++ b/core/pull_consumer_test.go
@@ -0,0 +1,47 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+package rocketmq
+
+import (
+	"errors"
+	"github.com/stretchr/testify/assert"
+	"testing"
+)
+
+func TestPullConsumer_PullStatus(t *testing.T) {
+	assert.Equal(t, "Found", PullStatus(int(PullFound)).String())
+	assert.Equal(t, "NoNewMsg", PullStatus(int(PullNoNewMsg)).String())
+	assert.Equal(t, "NoMatchedMsg", PullStatus(int(PullNoMatchedMsg)).String())
+	assert.Equal(t, "OffsetIllegal", PullStatus(int(PullOffsetIllegal)).String())
+	assert.Equal(t, "BrokerTimeout", PullStatus(int(PullBrokerTimeout)).String())
+	assert.Equal(t, "Unknown status", PullStatus(int(-1)).String())
+}
+
+func TestPullConsumer_CreatePullCosumerFailed(t *testing.T) {
+	pConfig := PullConsumerConfig{}
+
+	producer, err := NewPullConsumer(nil)
+	assert.Nil(t, producer)
+	assert.Equal(t, err, errors.New("config is nil"))
+	producer, err = NewPullConsumer(&pConfig)
+	assert.Nil(t, producer)
+	assert.Equal(t, err, errors.New("GroupId is empty"))
+	pConfig.GroupID = "testGroup"
+	producer, err = NewPullConsumer(&pConfig)
+	assert.Nil(t, producer)
+	assert.Equal(t, err, errors.New("NameServer and NameServerDomain is empty"))
+}
diff --git a/core/push_consumer_test.go b/core/push_consumer_test.go
index 22c1444..6f9a748 100644
--- a/core/push_consumer_test.go
+++ b/core/push_consumer_test.go
@@ -16,13 +16,96 @@
  */
 package rocketmq
 
-//import "fmt"
-//import "testing"
-//import "../client"
-//
-//func TestCreatePushConsumer(test *testing.T){
-//    fmt.Println("-----TestCreateProducer Start----")
-//    consumer := rocketmq.CreatePushConsumer("testGroupId")
-//    rocketmq.DestroyPushConsumer(consumer)
-//    fmt.Println("-----TestCreateProducer Finish----")
-//}
+import (
+	"errors"
+	"github.com/stretchr/testify/assert"
+	"testing"
+)
+
+func TestPushConsumer_ConsumeStatus(t *testing.T) {
+	assert.Equal(t, "ConsumeSuccess", ConsumeStatus(int(ConsumeSuccess)).String())
+	assert.Equal(t, "ReConsumeLater", ConsumeStatus(int(ReConsumeLater)).String())
+	assert.Equal(t, "Unknown", ConsumeStatus(int(-1)).String())
+}
+
+func TestPushConsumer_CreatePushConsumerFailed(t *testing.T) {
+	pConfig := PushConsumerConfig{}
+
+	consumer, err := newPushConsumer(nil)
+	assert.Nil(t, consumer)
+	assert.Equal(t, err, errors.New("config is nil"))
+	consumer, err = newPushConsumer(&pConfig)
+	assert.Nil(t, consumer)
+	assert.Equal(t, err, errors.New("GroupId is empty"))
+	pConfig.GroupID = "testGroup"
+	consumer, err = newPushConsumer(&pConfig)
+	assert.Nil(t, consumer)
+	assert.Equal(t, err, errors.New("NameServer and NameServerDomain is empty"))
+	pConfig.NameServer = "localhost:9876"
+	consumer, err = newPushConsumer(&pConfig)
+	assert.Nil(t, consumer)
+	assert.Equal(t, err, errors.New("model is invalid or empty"))
+	pConfig.Model = Clustering
+	consumer, err = newPushConsumer(&pConfig)
+	assert.Nil(t, consumer)
+	assert.Equal(t, err, errors.New("consumer model is invalid or empty"))
+	pConfig.ConsumerModel = CoCurrently
+	pConfig.MaxCacheMessageSizeInMB = 1024
+	consumer, err = newPushConsumer(&pConfig)
+}
+
+func TestPushConsumer_CreatePushConsumer(t *testing.T) {
+	pConfig := PushConsumerConfig{}
+	pConfig.GroupID = "testGroupA"
+	pConfig.NameServer = "localhost:9876"
+	pConfig.InstanceName = "testProducerA"
+	pConfig.Credentials = &SessionCredentials{
+		AccessKey: "AK",
+		SecretKey: "SK",
+		Channel:   "Cloud"}
+	pConfig.LogC = &LogConfig{
+		Path:     "/rocketmq/log",
+		FileNum:  16,
+		FileSize: 1 << 20,
+		Level:    LogLevelDebug}
+	pConfig.ConsumerModel = CoCurrently
+	pConfig.Model = Clustering
+	pConfig.ThreadCount = 3
+	pConfig.MessageBatchMaxSize = 1
+	pConfig.MaxCacheMessageSize = 1000
+	//pConfig.MaxCacheMessageSizeInMB = 1024
+	consumer, err := newPushConsumer(&pConfig)
+	assert.Nil(t, err)
+	assert.NotNil(t, consumer)
+}
+func callback_test(msg *MessageExt) ConsumeStatus {
+	return ReConsumeLater
+}
+func TestPushConsumer_CreatePushConsumerSubscribe(t *testing.T) {
+	pConfig := PushConsumerConfig{}
+	pConfig.GroupID = "testGroup"
+	pConfig.NameServer = "localhost:9876"
+	pConfig.InstanceName = "testProducer"
+	pConfig.Credentials = &SessionCredentials{
+		AccessKey: "AK",
+		SecretKey: "SK",
+		Channel:   "Cloud"}
+	pConfig.LogC = &LogConfig{
+		Path:     "/rocketmq/log",
+		FileNum:  16,
+		FileSize: 1 << 20,
+		Level:    LogLevelDebug}
+	pConfig.ConsumerModel = CoCurrently
+	pConfig.Model = Clustering
+	pConfig.ThreadCount = 3
+	pConfig.MessageBatchMaxSize = 1
+	pConfig.MaxCacheMessageSize = 1000
+	//pConfig.MaxCacheMessageSizeInMB = 1024
+	consumer, err := newPushConsumer(&pConfig)
+	assert.Nil(t, err)
+	assert.NotNil(t, consumer)
+	err = consumer.Subscribe("Topic", "exp", nil)
+	assert.Equal(t, err, errors.New("consumeFunc is nil"))
+	err = consumer.Subscribe("Topic", "exp", callback_test)
+	assert.Nil(t, err)
+}
diff --git a/core/queue_test.go b/core/queue_test.go
new file mode 100644
index 0000000..f172386
--- /dev/null
+++ b/core/queue_test.go
@@ -0,0 +1,31 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+package rocketmq
+
+import (
+	"github.com/stretchr/testify/assert"
+	"testing"
+)
+
+func TestMessageQueue_String(t *testing.T) {
+	mq := MessageQueue{
+		Topic:  "testTopic",
+		Broker: "BrokerA",
+		ID:     1}
+	expect := "broker:BrokerA, topic:testTopic, id:1"
+	assert.Equal(t, expect, mq.String())
+}
diff --git a/core/transaction_producer_test.go b/core/transaction_producer_test.go
new file mode 100644
index 0000000..3ef9e46
--- /dev/null
+++ b/core/transaction_producer_test.go
@@ -0,0 +1,77 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+package rocketmq
+
+import (
+	"errors"
+	"github.com/stretchr/testify/assert"
+	"testing"
+)
+
+func TestTransactionProducer_TransactionStatus(t *testing.T) {
+	assert.Equal(t, "CommitTransaction", TransactionStatus(int(CommitTransaction)).String())
+	assert.Equal(t, "RollbackTransaction", TransactionStatus(int(RollbackTransaction)).String())
+	assert.Equal(t, "UnknownTransaction", TransactionStatus(int(UnknownTransaction)).String())
+	assert.Equal(t, "UnknownTransaction", TransactionStatus(int(-1)).String())
+}
+
+func TestTransactionProducer_CreateProducerFailed(t *testing.T) {
+	pConfig := ProducerConfig{}
+
+	producer, err := newDefaultTransactionProducer(nil, nil, nil)
+	assert.Nil(t, producer)
+	assert.Equal(t, err, errors.New("config is nil"))
+	producer, err = newDefaultTransactionProducer(&pConfig, nil, nil)
+	assert.Nil(t, producer)
+	assert.Equal(t, err, errors.New("GroupId is empty"))
+	pConfig.GroupID = "testGroup"
+	producer, err = newDefaultTransactionProducer(&pConfig, nil, nil)
+	assert.Nil(t, producer)
+	assert.Equal(t, err, errors.New("NameServer and NameServerDomain is empty"))
+}
+
+type MyTransactionLocalListener struct {
+}
+
+func (l *MyTransactionLocalListener) Execute(m *Message, arg interface{}) TransactionStatus {
+	return UnknownTransaction
+}
+func (l *MyTransactionLocalListener) Check(m *MessageExt, arg interface{}) TransactionStatus {
+	return CommitTransaction
+}
+func TestTransactionProducer_CreateProducer(t *testing.T) {
+	pConfig := ProducerConfig{}
+	pConfig.GroupID = "testGroup"
+	pConfig.NameServer = "localhost:9876"
+	pConfig.InstanceName = "testProducer"
+	pConfig.Credentials = &SessionCredentials{
+		AccessKey: "AK",
+		SecretKey: "SK",
+		Channel:   "Cloud"}
+	pConfig.LogC = &LogConfig{
+		Path:     "/rocketmq/log",
+		FileNum:  16,
+		FileSize: 1 << 20,
+		Level:    LogLevelDebug}
+	pConfig.SendMsgTimeout = 30
+	pConfig.CompressLevel = 4
+	pConfig.MaxMessageSize = 1024
+	listener := &MyTransactionLocalListener{}
+	producer, err := newDefaultTransactionProducer(&pConfig, listener, nil)
+	assert.Nil(t, err)
+	assert.NotEmpty(t, producer)
+}
diff --git a/core/utils_test.go b/core/utils_test.go
new file mode 100644
index 0000000..93b0e0c
--- /dev/null
+++ b/core/utils_test.go
@@ -0,0 +1,26 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+package rocketmq
+
+import (
+	"github.com/stretchr/testify/assert"
+	"testing"
+)
+
+func TestUtils_strJoin(test *testing.T) {
+	assert.Equal(test, "TestKeyA: ValueA, ", strJoin("Test", "KeyA", "ValueA"))
+}