单元测试C#中的工厂类

时间:2017-03-13 20:03:30

标签: c# unit-testing dependency-injection rhino-mocks

我有第三方api包装类,需要使用用户名密码进行身份验证,所以我在Factory类中进行了初始化设置,如

public class ApiClientFactory
{
    private ApiClient apiClient;


    publi ApiClient GetApiClient()
    {
        try
        {
            String apiURL = ConfigurationManager.AppSettings["API_URL"];
            apiClient = new ApiClient(apiURL);

            // Auth to the API to get our JWT token for subsequent requests.
            AuthResponse response = apiClient.Authenticate(new AuthRequest()
            {
                Type = UserType.Staff,
                Username = ConfigurationManager.AppSettings["API_UserName"],
                Password = ConfigurationManager.AppSettings["API_Password"]
            });

            if (response != null)
            {
                //save the token for all subsequent requests
                apiClient.JwtToken = response.Token;
                response = null;
            }
            else
            {
                log.Error("APIClient Could not authenticate.");
            }

            return apiClient;
        }
        catch (Exception ex)
        {
            throw ex;
        }
    }
}

public static void Main()
{
    try
    {
        ApiClientFactory clientFactory = new ApiClientFactory();
        apiClient = clientFactory.GetApiClient();

    }
    catch (Exception ex)
    {
        log.Error(ex.Message);
        return;
    }

    // use apiClient to call api method 

}

如何对ApiClientFactory类的GetApiClient进行单元测试。

2 个答案:

答案 0 :(得分:1)

由于工厂直接实例化ApiClient,因此无法用模拟替换ApiClient,因此如果不实际向服务器发出请求,则无法测试工厂。您的工厂不应该执行身份验证,它应该只创建对象并将其返回。

答案 1 :(得分:0)

如果将APIClient的用法移动到单独的方法中,特别是Authenticate调用,并将这些方法标记为虚拟,则可以模拟提取的方法以测试工厂逻辑的其余部分。像这样:

public ApiClient GetApiClient()
{
    try
    {
        String apiURL = ConfigurationManager.AppSettings["API_URL"];
        apiClient = new ApiClient(apiURL);

        // Auth to the API to get our JWT token for subsequent requests.
        var request = new AuthRequest()
        {
            Type = UserType.Staff,
            Username = ConfigurationManager.AppSettings["API_UserName"],
            Password = ConfigurationManager.AppSettings["API_Password"]
        });
        AuthResponse response = Authenticate(apiClient, request);

        if (response != null)
        {
            //save the token for all subsequent requests
            apiClient.JwtToken = response.Token;
            response = null;
        }
        else
        {
            log.Error("APIClient Could not authenticate.");
        }

        return apiClient;
    }
    catch (Exception ex)
    {
        throw ex;
    }
}

internal virtual AuthResponse Authenticate(ApiClient apiClient, AuthRequest request)
{
    return apiClient.Authenticate(request);
}

然后,在你的测试中,你会做这样的事情:

public void MyTest() 
{
    var factoryMock = MockRepository.GeneratePartialMock<ApiClientFactory>();
    factoryMock.Expect(x => x.Authenticate(...).Return(...);

    var client  = factoryMock.GetApiClient();

    Assert.That(client.xxx, Is.EqualTo(...));
}

显然,填写您想用来验证逻辑的任何验证和期望。