[图一] 是单元测试代码?
[图二] 是产品代码?
显而易见的是, 单元测试代码比产品代码还要多, 这合理吗?
当然合理!
产品代码虽然是只有短短的几行; 处理订阅者订阅赛马的消息?
但, 却会衍生出许多不同的使用者场景; 如: 没有订阅者订阅, 只有单一或多个订阅者, 某个订阅者重复订阅, 某个订阅者取消订阅…..等等?
单元测试, 根据这些不同的使用者场景, 分别有相对应的单元测试代码 (测试用例) ? 所以, 单元测试代码自然会比产品代码还要多?
但, 这样的付出 (投资) 绝对是值得的?
因为, 唯有如此所形成的 “自动化单元测试”, 才能使产品可在 “最短的时间内反馈”, 既有产品的架构, 功能与质量是否已被所新增的代码 (功能) 所破坏?
所以, 我们应该真正专注的是, 单元测试的 “测试用例的有效性” , 而不是表面的单元测试代码的行数?
package test.java.com;
import main.java.com.Client;
import main.java.com.Message;
import main.java.com.RaceResultsService;
import org.junit.Before;
import org.junit.Test;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
/**
* Created by ScalaMind on 2015/3/3.
*/
public class RaceResultsServiceTest
{
private RaceResultsServiceraceResults;
private Messagemessage;
private ClientclientA;
private ClientclientB;
@Before
public void setUp() {
raceResults =
new RaceResultsService();
message =
mock(Message.class);
clientA =
mock(Client.class,
"clientA");
clientB =
mock(Client.class,
"clientB");
}
// zero subscribers
@Test
public void notSubscribeClientShouldNotReceiveMessage() {
raceResults.send(message);
verify(clientA,
never()).receive(message);
verify(clientB,
never()).receive(message);
}
// one subscriber
@Test
public void subscribedClientShouldReceiveMessage() {
raceResults.addSubscriber(clientA);
raceResults.send(message);
verify(clientA).receive(message);
}
// two subscribers
@Test
public void messageShouldBeSentToAllSubscribedClients() {
RaceResultsService raceResults=
new RaceResultsService();
Message message
= mock(Message.class);
raceResults.addSubscriber(clientA);
raceResults.addSubscriber(clientB);
raceResults.send(message);
verify(clientA).receive(message);
verify(clientB).receive(message);
}
// subscribe more than once
@Test
public void shouldSendOnlyOneMessageToMultiSubscriber() {
raceResults.addSubscriber(clientA);
raceResults.addSubscriber(clientA);
raceResults.send(message);
verify(clientA).receive(message);
}
// remove a subscriber
@Test
public void unsubscribedClientShouldNotReceiveMessages() {
raceResults.addSubscriber(clientA);
raceResults.removeSubscriber(clientA);
raceResults.send(message);
verify(clientA,
never()).receive(message);
}
}
[图一: 单元测试代码]
package main.java.com;
import java.util.Collection;
import java.util.HashSet;
/**
* Created by ScalaMind on 2015/3/3.
*/
public class RaceResultsService
{
private Collection<Client>
clients =
new HashSet<Client>();
public void addSubscriber(Client
client) {
clients.add(client);
}
public void send(Message
message) {
for (Client
client :
clients)
client.receive(message);
}
public void removeSubscriber(Client
client) {
clients.remove(client);
}
}
[图二: 产品代码]